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 18 package org.apache.harmony.xnet.provider.jsse; 19 20 import java.security.Principal; 21 import java.security.SecureRandom; 22 import java.security.cert.Certificate; 23 import java.security.cert.CertificateEncodingException; 24 import java.security.cert.X509Certificate; 25 import java.util.HashMap; 26 import java.util.Map; 27 import javax.net.ssl.SSLPeerUnverifiedException; 28 import javax.net.ssl.SSLSession; 29 import javax.net.ssl.SSLSessionBindingEvent; 30 import javax.net.ssl.SSLSessionBindingListener; 31 import javax.net.ssl.SSLSessionContext; 32 import libcore.util.EmptyArray; 33 34 public final class SSLSessionImpl implements SSLSession, Cloneable { 35 36 /** Session object reporting an invalid cipher suite of "SSL_NULL_WITH_NULL_NULL" */ 37 public static final SSLSessionImpl NULL_SESSION = new SSLSessionImpl(null); 38 39 private long creationTime; 40 private boolean isValid = true; 41 private final Map<String, Object> values = new HashMap<String, Object>(); 42 43 byte[] id; 44 long lastAccessedTime; 45 ProtocolVersion protocol; 46 CipherSuite cipherSuite; 47 SSLSessionContext context; 48 X509Certificate[] localCertificates; 49 X509Certificate[] peerCertificates; 50 private String peerHost; 51 private int peerPort = -1; 52 byte[] master_secret; 53 byte[] clientRandom; 54 byte[] serverRandom; 55 final boolean isServer; 56 57 public SSLSessionImpl(CipherSuite cipher_suite, SecureRandom secureRandom) { 58 creationTime = System.currentTimeMillis(); 59 lastAccessedTime = creationTime; 60 if (cipher_suite == null) { 61 this.cipherSuite = CipherSuite.SSL_NULL_WITH_NULL_NULL; 62 id = EmptyArray.BYTE; 63 isServer = false; 64 isValid = false; 65 } else { 66 this.cipherSuite = cipher_suite; 67 id = new byte[32]; 68 secureRandom.nextBytes(id); 69 long time = creationTime / 1000; 70 id[28] = (byte) ((time & 0xFF000000) >>> 24); 71 id[29] = (byte) ((time & 0x00FF0000) >>> 16); 72 id[30] = (byte) ((time & 0x0000FF00) >>> 8); 73 id[31] = (byte) ((time & 0x000000FF)); 74 isServer = true; 75 } 76 77 } 78 79 public SSLSessionImpl(SecureRandom secureRandom) { 80 this(null, secureRandom); 81 } 82 83 public int getApplicationBufferSize() { 84 return SSLRecordProtocol.MAX_DATA_LENGTH; 85 } 86 87 public String getCipherSuite() { 88 return cipherSuite.getName(); 89 } 90 91 public long getCreationTime() { 92 return creationTime; 93 } 94 95 public byte[] getId() { 96 return id; 97 } 98 99 public long getLastAccessedTime() { 100 return lastAccessedTime; 101 } 102 103 public Certificate[] getLocalCertificates() { 104 return localCertificates; 105 } 106 107 public Principal getLocalPrincipal() { 108 if (localCertificates != null && localCertificates.length > 0) { 109 return localCertificates[0].getSubjectX500Principal(); 110 } 111 return null; 112 } 113 114 public int getPacketBufferSize() { 115 return SSLRecordProtocol.MAX_SSL_PACKET_SIZE; 116 } 117 118 public javax.security.cert.X509Certificate[] getPeerCertificateChain() 119 throws SSLPeerUnverifiedException { 120 if (peerCertificates == null) { 121 throw new SSLPeerUnverifiedException("No peer certificate"); 122 } 123 javax.security.cert.X509Certificate[] certs = new javax.security.cert.X509Certificate[peerCertificates.length]; 124 for (int i = 0; i < certs.length; i++) { 125 try { 126 certs[i] = javax.security.cert.X509Certificate.getInstance(peerCertificates[i] 127 .getEncoded()); 128 } catch (javax.security.cert.CertificateException ignored) { 129 } catch (CertificateEncodingException ignored) { 130 } 131 } 132 return certs; 133 } 134 135 public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { 136 if (peerCertificates == null) { 137 throw new SSLPeerUnverifiedException("No peer certificate"); 138 } 139 return peerCertificates; 140 } 141 142 public String getPeerHost() { 143 return peerHost; 144 } 145 146 public int getPeerPort() { 147 return peerPort; 148 } 149 150 public Principal getPeerPrincipal() throws SSLPeerUnverifiedException { 151 if (peerCertificates == null) { 152 throw new SSLPeerUnverifiedException("No peer certificate"); 153 } 154 return peerCertificates[0].getSubjectX500Principal(); 155 } 156 157 public String getProtocol() { 158 return (protocol == null) ? "NONE" : protocol.name; 159 } 160 161 public SSLSessionContext getSessionContext() { 162 return context; 163 } 164 165 public Object getValue(String name) { 166 if (name == null) { 167 throw new IllegalArgumentException("name == null"); 168 } 169 return values.get(name); 170 } 171 172 public String[] getValueNames() { 173 return values.keySet().toArray(new String[values.size()]); 174 } 175 176 public void invalidate() { 177 isValid = false; 178 context = null; 179 } 180 181 public boolean isValid() { 182 if (isValid && context != null && context.getSessionTimeout() != 0 183 && lastAccessedTime + context.getSessionTimeout() > System.currentTimeMillis()) { 184 isValid = false; 185 } 186 return isValid; 187 } 188 189 public void putValue(String name, Object value) { 190 if (name == null || value == null) { 191 throw new IllegalArgumentException("name == null || value == null"); 192 } 193 Object old = values.put(name, value); 194 if (value instanceof SSLSessionBindingListener) { 195 ((SSLSessionBindingListener) value).valueBound(new SSLSessionBindingEvent(this, name)); 196 } 197 if (old instanceof SSLSessionBindingListener) { 198 ((SSLSessionBindingListener) old).valueUnbound(new SSLSessionBindingEvent(this, name)); 199 } 200 201 } 202 203 public void removeValue(String name) { 204 if (name == null) { 205 throw new IllegalArgumentException("name == null"); 206 } 207 Object old = values.remove(name); 208 if (old instanceof SSLSessionBindingListener) { 209 SSLSessionBindingListener listener = (SSLSessionBindingListener) old; 210 listener.valueUnbound(new SSLSessionBindingEvent(this, name)); 211 } 212 } 213 214 @Override 215 public Object clone() { 216 try { 217 return super.clone(); 218 } catch (CloneNotSupportedException e) { 219 throw new AssertionError(e); 220 } 221 } 222 223 void setPeer(String peerHost, int peerPort) { 224 this.peerHost = peerHost; 225 this.peerPort = peerPort; 226 } 227 } 228