SSLSessionImpl.java revision f33eae7e84eb6d3b0f4e86b59605bb3de73009f3
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 isValid = false; 181 } else { 182 this.cipherSuite = cipher_suite; 183 id = new byte[32]; 184 sr.nextBytes(id); 185 long time = creationTime / 1000; 186 id[28] = (byte) ((time & 0xFF000000) >>> 24); 187 id[29] = (byte) ((time & 0x00FF0000) >>> 16); 188 id[30] = (byte) ((time & 0x0000FF00) >>> 8); 189 id[31] = (byte) ((time & 0x000000FF)); 190 isServer = true; 191 } 192 193 } 194 195 /** 196 * Creates SSLSession implementation 197 * 198 * @param sr 199 */ 200 public SSLSessionImpl(SecureRandom sr) { 201 this(null, sr); 202 } 203 204 public int getApplicationBufferSize() { 205 return SSLRecordProtocol.MAX_DATA_LENGTH; 206 } 207 208 public String getCipherSuite() { 209 return cipherSuite.getName(); 210 } 211 212 public long getCreationTime() { 213 return creationTime; 214 } 215 216 public byte[] getId() { 217 return id; 218 } 219 220 public long getLastAccessedTime() { 221 return lastAccessedTime; 222 } 223 224 public Certificate[] getLocalCertificates() { 225 return localCertificates; 226 } 227 228 public Principal getLocalPrincipal() { 229 if (localCertificates != null && localCertificates.length > 0) { 230 return localCertificates[0].getSubjectX500Principal(); 231 } 232 return null; 233 } 234 235 public int getPacketBufferSize() { 236 return SSLRecordProtocol.MAX_SSL_PACKET_SIZE; 237 } 238 239 public javax.security.cert.X509Certificate[] getPeerCertificateChain() 240 throws SSLPeerUnverifiedException { 241 if (peerCertificates == null) { 242 throw new SSLPeerUnverifiedException("No peer certificate"); 243 } 244 javax.security.cert.X509Certificate[] certs = new javax.security.cert.X509Certificate[peerCertificates.length]; 245 for (int i = 0; i < certs.length; i++) { 246 try { 247 certs[i] = javax.security.cert.X509Certificate.getInstance(peerCertificates[i] 248 .getEncoded()); 249 } catch (javax.security.cert.CertificateException e) { 250 } catch (CertificateEncodingException e) { 251 } 252 } 253 return certs; 254 } 255 256 public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { 257 if (peerCertificates == null) { 258 throw new SSLPeerUnverifiedException("No peer certificate"); 259 } 260 return peerCertificates; 261 } 262 263 public String getPeerHost() { 264 return peerHost; 265 } 266 267 public int getPeerPort() { 268 return peerPort; 269 } 270 271 public Principal getPeerPrincipal() throws SSLPeerUnverifiedException { 272 if (peerCertificates == null) { 273 throw new SSLPeerUnverifiedException("No peer certificate"); 274 } 275 return peerCertificates[0].getSubjectX500Principal(); 276 } 277 278 public String getProtocol() { 279 return (protocol == null) ? "NONE" : protocol.name; 280 } 281 282 public SSLSessionContext getSessionContext() { 283 SecurityManager sm = System.getSecurityManager(); 284 if (sm != null) { 285 sm.checkPermission(new SSLPermission("getSSLSessionContext")); 286 } 287 return context; 288 } 289 290 public Object getValue(String name) { 291 if (name == null) { 292 throw new IllegalArgumentException("Parameter is null"); 293 } 294 return values.get(new ValueKey(name)); 295 } 296 297 public String[] getValueNames() { 298 final Vector<String> v = new Vector<String>(); 299 final AccessControlContext currAcc = AccessController.getContext(); 300 for (ValueKey key : values.keySet()) { 301 if ((currAcc == null && key.acc == null) 302 || (currAcc != null && currAcc.equals(key.acc))) { 303 v.add(key.name); 304 } 305 } 306 return v.toArray(new String[v.size()]); 307 } 308 309 public void invalidate() { 310 isValid = false; 311 context = null; 312 } 313 314 public boolean isValid() { 315 if (isValid && context != null && context.getSessionTimeout() != 0 316 && lastAccessedTime + context.getSessionTimeout() > System.currentTimeMillis()) { 317 isValid = false; 318 } 319 return isValid; 320 } 321 322 public void putValue(String name, Object value) { 323 if (name == null || value == null) { 324 throw new IllegalArgumentException("Parameter is null"); 325 } 326 Object old = values.put(new ValueKey(name), value); 327 if (value instanceof SSLSessionBindingListener) { 328 ((SSLSessionBindingListener) value).valueBound(new SSLSessionBindingEvent(this, name)); 329 } 330 if (old instanceof SSLSessionBindingListener) { 331 ((SSLSessionBindingListener) old).valueUnbound(new SSLSessionBindingEvent(this, name)); 332 } 333 334 } 335 336 public void removeValue(String name) { 337 if (name == null) { 338 throw new IllegalArgumentException("Parameter is null"); 339 } 340 Object old = values.remove(new ValueKey(name)); 341 if (old instanceof SSLSessionBindingListener) { 342 SSLSessionBindingListener listener = (SSLSessionBindingListener) old; 343 listener.valueUnbound(new SSLSessionBindingEvent(this, name)); 344 } 345 } 346 347 @Override 348 public Object clone() { 349 try { 350 return super.clone(); 351 } catch (CloneNotSupportedException e) { 352 throw new AssertionError(e); 353 } 354 } 355 356 /** 357 * Sets the address of the peer 358 * 359 * @param peerHost 360 * @param peerPort 361 */ 362 void setPeer(String peerHost, int peerPort) { 363 this.peerHost = peerHost; 364 this.peerPort = peerPort; 365 } 366} 367