1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package org.apache.harmony.xnet.provider.jsse; 19 20import java.security.AccessControlContext; 21import java.security.AccessController; 22import java.security.Principal; 23import java.security.SecureRandom; 24import java.security.cert.Certificate; 25import java.security.cert.CertificateEncodingException; 26import java.security.cert.X509Certificate; 27import java.util.HashMap; 28import java.util.Map; 29import java.util.Vector; 30 31import javax.net.ssl.SSLPeerUnverifiedException; 32import javax.net.ssl.SSLPermission; 33import javax.net.ssl.SSLSession; 34import javax.net.ssl.SSLSessionBindingEvent; 35import javax.net.ssl.SSLSessionBindingListener; 36import javax.net.ssl.SSLSessionContext; 37 38/** 39 * 40 * SSLSession implementation 41 * 42 * @see javax.net.ssl.SSLSession 43 */ 44public class SSLSessionImpl implements SSLSession, Cloneable { 45 46 /** 47 * Session object reporting an invalid cipher suite of "SSL_NULL_WITH_NULL_NULL" 48 */ 49 public static final SSLSessionImpl NULL_SESSION = new SSLSessionImpl(null); 50 51 /** 52 * Container class for the 'value' map's keys. 53 */ 54 private static final class ValueKey { 55 final String name; 56 final AccessControlContext acc; 57 58 ValueKey(String name) { 59 super(); 60 this.name = name; 61 this.acc = AccessController.getContext(); 62 } 63 64 @Override 65 public int hashCode() { 66 final int prime = 31; 67 int result = 1; 68 result = prime * result + ((acc == null) ? 0 : acc.hashCode()); 69 result = prime * result + ((name == null) ? 0 : name.hashCode()); 70 return result; 71 } 72 73 @Override 74 public boolean equals(Object obj) { 75 if (this == obj) 76 return true; 77 if (obj == null) 78 return false; 79 if (!(obj instanceof ValueKey)) 80 return false; 81 ValueKey other = (ValueKey) obj; 82 if (acc == null) { 83 if (other.acc != null) 84 return false; 85 } else if (!acc.equals(other.acc)) 86 return false; 87 if (name == null) { 88 if (other.name != null) 89 return false; 90 } else if (!name.equals(other.name)) 91 return false; 92 return true; 93 } 94 } 95 96 private long creationTime; 97 private boolean isValid = true; 98 private Map<ValueKey, Object> values = new HashMap<ValueKey, Object>(); 99 100 /** 101 * ID of the session 102 */ 103 byte[] id; 104 105 /** 106 * Last time the session was accessed 107 */ 108 long lastAccessedTime; 109 110 /** 111 * Protocol used in the session 112 */ 113 ProtocolVersion protocol; 114 115 /** 116 * CipherSuite used in the session 117 */ 118 CipherSuite cipherSuite; 119 120 /** 121 * Context of the session 122 */ 123// BEGIN android-changed 124 SSLSessionContext context; 125// END android-changed 126 127 /** 128 * certificates were sent to the peer 129 */ 130 X509Certificate[] localCertificates; 131 132 /** 133 * Peer certificates 134 */ 135 X509Certificate[] peerCertificates; 136 137 /** 138 * Peer host name 139 */ 140 private String peerHost; 141 142 /** 143 * Peer port number 144 */ 145 private int peerPort = -1; 146 147 /** 148 * Master secret 149 */ 150 byte[] master_secret; 151 152 /** 153 * clientRandom 154 */ 155 byte[] clientRandom; 156 157 /** 158 * serverRandom 159 */ 160 byte[] serverRandom; 161 162 /** 163 * True if this entity is considered the server 164 */ 165 final boolean isServer; 166 167 /** 168 * Creates SSLSession implementation 169 * 170 * @param cipher_suite 171 * @param sr 172 */ 173 public SSLSessionImpl(CipherSuite cipher_suite, SecureRandom sr) { 174 creationTime = System.currentTimeMillis(); 175 lastAccessedTime = creationTime; 176 if (cipher_suite == null) { 177 this.cipherSuite = CipherSuite.TLS_NULL_WITH_NULL_NULL; 178 id = new byte[0]; 179 isServer = false; 180 } else { 181 this.cipherSuite = cipher_suite; 182 id = new byte[32]; 183 sr.nextBytes(id); 184 long time = creationTime / 1000; 185 id[28] = (byte) ((time & 0xFF000000) >>> 24); 186 id[29] = (byte) ((time & 0x00FF0000) >>> 16); 187 id[30] = (byte) ((time & 0x0000FF00) >>> 8); 188 id[31] = (byte) ((time & 0x000000FF)); 189 isServer = true; 190 } 191 192 } 193 194 /** 195 * Creates SSLSession implementation 196 * 197 * @param sr 198 */ 199 public SSLSessionImpl(SecureRandom sr) { 200 this(null, sr); 201 } 202 203 public int getApplicationBufferSize() { 204 return SSLRecordProtocol.MAX_DATA_LENGTH; 205 } 206 207 public String getCipherSuite() { 208 return cipherSuite.getName(); 209 } 210 211 public long getCreationTime() { 212 return creationTime; 213 } 214 215 public byte[] getId() { 216 return id; 217 } 218 219 public long getLastAccessedTime() { 220 return lastAccessedTime; 221 } 222 223 public Certificate[] getLocalCertificates() { 224 return localCertificates; 225 } 226 227 public Principal getLocalPrincipal() { 228 if (localCertificates != null && localCertificates.length > 0) { 229 return localCertificates[0].getSubjectX500Principal(); 230 } 231 return null; 232 } 233 234 public int getPacketBufferSize() { 235 return SSLRecordProtocol.MAX_SSL_PACKET_SIZE; 236 } 237 238 public javax.security.cert.X509Certificate[] getPeerCertificateChain() 239 throws SSLPeerUnverifiedException { 240 if (peerCertificates == null) { 241 throw new SSLPeerUnverifiedException("No peer certificate"); 242 } 243 javax.security.cert.X509Certificate[] certs = new javax.security.cert.X509Certificate[peerCertificates.length]; 244 for (int i = 0; i < certs.length; i++) { 245 try { 246 certs[i] = javax.security.cert.X509Certificate.getInstance(peerCertificates[i] 247 .getEncoded()); 248 } catch (javax.security.cert.CertificateException e) { 249 } catch (CertificateEncodingException e) { 250 } 251 } 252 return certs; 253 } 254 255 public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { 256 if (peerCertificates == null) { 257 throw new SSLPeerUnverifiedException("No peer certificate"); 258 } 259 return peerCertificates; 260 } 261 262 public String getPeerHost() { 263 return peerHost; 264 } 265 266 public int getPeerPort() { 267 return peerPort; 268 } 269 270 public Principal getPeerPrincipal() throws SSLPeerUnverifiedException { 271 if (peerCertificates == null) { 272 throw new SSLPeerUnverifiedException("No peer certificate"); 273 } 274 return peerCertificates[0].getSubjectX500Principal(); 275 } 276 277 public String getProtocol() { 278 return protocol.name; 279 } 280 281 public SSLSessionContext getSessionContext() { 282 SecurityManager sm = System.getSecurityManager(); 283 if (sm != null) { 284 sm.checkPermission(new SSLPermission("getSSLSessionContext")); 285 } 286 return context; 287 } 288 289 public Object getValue(String name) { 290 if (name == null) { 291 throw new IllegalArgumentException("Parameter is null"); 292 } 293 return values.get(new ValueKey(name)); 294 } 295 296 public String[] getValueNames() { 297 final Vector<String> v = new Vector<String>(); 298 final AccessControlContext currAcc = AccessController.getContext(); 299 for (ValueKey key : values.keySet()) { 300 if ((currAcc == null && key.acc == null) 301 || (currAcc != null && currAcc.equals(key.acc))) { 302 v.add(key.name); 303 } 304 } 305 return v.toArray(new String[v.size()]); 306 } 307 308 public void invalidate() { 309 isValid = false; 310 } 311 312 public boolean isValid() { 313 if (isValid && context != null && context.getSessionTimeout() != 0 314 && lastAccessedTime + context.getSessionTimeout() > System.currentTimeMillis()) { 315 isValid = false; 316 } 317 return isValid; 318 } 319 320 public void putValue(String name, Object value) { 321 if (name == null || value == null) { 322 throw new IllegalArgumentException("Parameter is null"); 323 } 324 Object old = values.put(new ValueKey(name), value); 325 if (value instanceof SSLSessionBindingListener) { 326 ((SSLSessionBindingListener) value).valueBound(new SSLSessionBindingEvent(this, name)); 327 } 328 if (old instanceof SSLSessionBindingListener) { 329 ((SSLSessionBindingListener) old).valueUnbound(new SSLSessionBindingEvent(this, name)); 330 } 331 332 } 333 334 public void removeValue(String name) { 335 if (name == null) { 336 throw new IllegalArgumentException("Parameter is null"); 337 } 338 Object old = values.remove(new ValueKey(name)); 339 if (old instanceof SSLSessionBindingListener) { 340 SSLSessionBindingListener listener = (SSLSessionBindingListener) old; 341 listener.valueUnbound(new SSLSessionBindingEvent(this, name)); 342 } 343 } 344 345 @Override 346 public Object clone() { 347 try { 348 return super.clone(); 349 } catch (CloneNotSupportedException e) { 350 throw new AssertionError(e); 351 } 352 } 353 354 /** 355 * Sets the address of the peer 356 * 357 * @param peerHost 358 * @param peerPort 359 */ 360 void setPeer(String peerHost, int peerPort) { 361 this.peerHost = peerHost; 362 this.peerPort = peerPort; 363 } 364} 365