SSLSessionImpl.java revision 32c2297a959b72abdb18743f0519e1d8b7c7ea88
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.ArrayList; 28import java.util.HashMap; 29import java.util.Map; 30import javax.net.ssl.SSLPeerUnverifiedException; 31import javax.net.ssl.SSLPermission; 32import javax.net.ssl.SSLSession; 33import javax.net.ssl.SSLSessionBindingEvent; 34import javax.net.ssl.SSLSessionBindingListener; 35import javax.net.ssl.SSLSessionContext; 36import libcore.util.EmptyArray; 37import libcore.util.Objects; 38 39/** 40 * 41 * SSLSession implementation 42 * 43 * @see javax.net.ssl.SSLSession 44 */ 45public class SSLSessionImpl implements SSLSession, Cloneable { 46 47 /** 48 * Session object reporting an invalid cipher suite of "SSL_NULL_WITH_NULL_NULL" 49 */ 50 public static final SSLSessionImpl NULL_SESSION = new SSLSessionImpl(null); 51 52 /** 53 * Container class for the 'value' map's keys. 54 */ 55 private static final class ValueKey { 56 final String name; 57 final AccessControlContext acc; 58 59 ValueKey(String name) { 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 SSLSessionContext context; 124 125 /** 126 * certificates were sent to the peer 127 */ 128 X509Certificate[] localCertificates; 129 130 /** 131 * Peer certificates 132 */ 133 X509Certificate[] peerCertificates; 134 135 /** 136 * Peer host name 137 */ 138 private String peerHost; 139 140 /** 141 * Peer port number 142 */ 143 private int peerPort = -1; 144 145 /** 146 * Master secret 147 */ 148 byte[] master_secret; 149 150 /** 151 * clientRandom 152 */ 153 byte[] clientRandom; 154 155 /** 156 * serverRandom 157 */ 158 byte[] serverRandom; 159 160 /** 161 * True if this entity is considered the server 162 */ 163 final boolean isServer; 164 165 /** 166 * Creates SSLSession implementation 167 * 168 * @param cipher_suite 169 * @param sr 170 */ 171 public SSLSessionImpl(CipherSuite cipher_suite, SecureRandom sr) { 172 creationTime = System.currentTimeMillis(); 173 lastAccessedTime = creationTime; 174 if (cipher_suite == null) { 175 this.cipherSuite = CipherSuite.SSL_NULL_WITH_NULL_NULL; 176 id = EmptyArray.BYTE; 177 isServer = false; 178 isValid = false; 179 } else { 180 this.cipherSuite = cipher_suite; 181 id = new byte[32]; 182 sr.nextBytes(id); 183 long time = creationTime / 1000; 184 id[28] = (byte) ((time & 0xFF000000) >>> 24); 185 id[29] = (byte) ((time & 0x00FF0000) >>> 16); 186 id[30] = (byte) ((time & 0x0000FF00) >>> 8); 187 id[31] = (byte) ((time & 0x000000FF)); 188 isServer = true; 189 } 190 191 } 192 193 /** 194 * Creates SSLSession implementation 195 * 196 * @param sr 197 */ 198 public SSLSessionImpl(SecureRandom sr) { 199 this(null, sr); 200 } 201 202 public int getApplicationBufferSize() { 203 return SSLRecordProtocol.MAX_DATA_LENGTH; 204 } 205 206 public String getCipherSuite() { 207 return cipherSuite.getName(); 208 } 209 210 public long getCreationTime() { 211 return creationTime; 212 } 213 214 public byte[] getId() { 215 return id; 216 } 217 218 public long getLastAccessedTime() { 219 return lastAccessedTime; 220 } 221 222 public Certificate[] getLocalCertificates() { 223 return localCertificates; 224 } 225 226 public Principal getLocalPrincipal() { 227 if (localCertificates != null && localCertificates.length > 0) { 228 return localCertificates[0].getSubjectX500Principal(); 229 } 230 return null; 231 } 232 233 public int getPacketBufferSize() { 234 return SSLRecordProtocol.MAX_SSL_PACKET_SIZE; 235 } 236 237 public javax.security.cert.X509Certificate[] getPeerCertificateChain() 238 throws SSLPeerUnverifiedException { 239 if (peerCertificates == null) { 240 throw new SSLPeerUnverifiedException("No peer certificate"); 241 } 242 javax.security.cert.X509Certificate[] certs = new javax.security.cert.X509Certificate[peerCertificates.length]; 243 for (int i = 0; i < certs.length; i++) { 244 try { 245 certs[i] = javax.security.cert.X509Certificate.getInstance(peerCertificates[i] 246 .getEncoded()); 247 } catch (javax.security.cert.CertificateException e) { 248 } catch (CertificateEncodingException e) { 249 } 250 } 251 return certs; 252 } 253 254 public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { 255 if (peerCertificates == null) { 256 throw new SSLPeerUnverifiedException("No peer certificate"); 257 } 258 return peerCertificates; 259 } 260 261 public String getPeerHost() { 262 return peerHost; 263 } 264 265 public int getPeerPort() { 266 return peerPort; 267 } 268 269 public Principal getPeerPrincipal() throws SSLPeerUnverifiedException { 270 if (peerCertificates == null) { 271 throw new SSLPeerUnverifiedException("No peer certificate"); 272 } 273 return peerCertificates[0].getSubjectX500Principal(); 274 } 275 276 public String getProtocol() { 277 return (protocol == null) ? "NONE" : protocol.name; 278 } 279 280 public SSLSessionContext getSessionContext() { 281 return context; 282 } 283 284 public Object getValue(String name) { 285 if (name == null) { 286 throw new IllegalArgumentException("Parameter is null"); 287 } 288 return values.get(new ValueKey(name)); 289 } 290 291 public String[] getValueNames() { 292 final ArrayList<String> v = new ArrayList<String>(); 293 final AccessControlContext currAcc = AccessController.getContext(); 294 for (ValueKey key : values.keySet()) { 295 if (Objects.equal(currAcc, key.acc)) { 296 v.add(key.name); 297 } 298 } 299 return v.toArray(new String[v.size()]); 300 } 301 302 public void invalidate() { 303 isValid = false; 304 context = null; 305 } 306 307 public boolean isValid() { 308 if (isValid && context != null && context.getSessionTimeout() != 0 309 && lastAccessedTime + context.getSessionTimeout() > System.currentTimeMillis()) { 310 isValid = false; 311 } 312 return isValid; 313 } 314 315 public void putValue(String name, Object value) { 316 if (name == null || value == null) { 317 throw new IllegalArgumentException("Parameter is null"); 318 } 319 Object old = values.put(new ValueKey(name), value); 320 if (value instanceof SSLSessionBindingListener) { 321 ((SSLSessionBindingListener) value).valueBound(new SSLSessionBindingEvent(this, name)); 322 } 323 if (old instanceof SSLSessionBindingListener) { 324 ((SSLSessionBindingListener) old).valueUnbound(new SSLSessionBindingEvent(this, name)); 325 } 326 327 } 328 329 public void removeValue(String name) { 330 if (name == null) { 331 throw new IllegalArgumentException("Parameter is null"); 332 } 333 Object old = values.remove(new ValueKey(name)); 334 if (old instanceof SSLSessionBindingListener) { 335 SSLSessionBindingListener listener = (SSLSessionBindingListener) old; 336 listener.valueUnbound(new SSLSessionBindingEvent(this, name)); 337 } 338 } 339 340 @Override 341 public Object clone() { 342 try { 343 return super.clone(); 344 } catch (CloneNotSupportedException e) { 345 throw new AssertionError(e); 346 } 347 } 348 349 /** 350 * Sets the address of the peer 351 * 352 * @param peerHost 353 * @param peerPort 354 */ 355 void setPeer(String peerHost, int peerPort) { 356 this.peerHost = peerHost; 357 this.peerPort = peerPort; 358 } 359} 360