001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Boris Kuznetsov
020: * @version $Revision$
021: */package org.apache.harmony.xnet.provider.jsse;
022:
023: import java.security.AccessControlContext;
024: import java.security.AccessController;
025: import java.security.Principal;
026: import java.security.SecureRandom;
027: import java.security.cert.Certificate;
028: import java.security.cert.CertificateEncodingException;
029: import java.security.cert.X509Certificate;
030: import java.util.Iterator;
031: import java.util.Vector;
032:
033: import javax.net.ssl.SSLPeerUnverifiedException;
034: import javax.net.ssl.SSLPermission;
035: import javax.net.ssl.SSLSession;
036: import javax.net.ssl.SSLSessionBindingEvent;
037: import javax.net.ssl.SSLSessionBindingListener;
038: import javax.net.ssl.SSLSessionContext;
039:
040: import org.apache.harmony.luni.util.TwoKeyHashMap;
041: import org.apache.harmony.xnet.provider.jsse.SSLSessionContextImpl;
042:
043: /**
044: *
045: * SSLSession implementation
046: *
047: * @see javax.net.ssl.SSLSession
048: */
049: public class SSLSessionImpl implements SSLSession {
050:
051: /**
052: * Session object reporting an invalid cipher suite of
053: * "SSL_NULL_WITH_NULL_NULL"
054: */
055: public static final SSLSessionImpl NULL_SESSION = new SSLSessionImpl(
056: null);
057:
058: private long creationTime;
059: private boolean isValid = true;
060: private TwoKeyHashMap values = new TwoKeyHashMap();
061:
062: /**
063: * ID of the session
064: */
065: byte[] id;
066:
067: /**
068: * Last time the session was accessed
069: */
070: long lastAccessedTime;
071:
072: /**
073: * Protocol used in the session
074: */
075: ProtocolVersion protocol;
076:
077: /**
078: * CipherSuite used in the session
079: */
080: CipherSuite cipherSuite;
081:
082: /**
083: * Context of the session
084: */
085: SSLSessionContextImpl context;
086:
087: /**
088: * certificates were sent to the peer
089: */
090: X509Certificate[] localCertificates;
091:
092: /**
093: * Peer certificates
094: */
095: X509Certificate[] peerCertificates;
096:
097: /**
098: * Peer host name
099: */
100: String peerHost;
101:
102: /**
103: * Peer port number
104: */
105: int peerPort = -1;
106:
107: /**
108: * Master secret
109: */
110: byte[] master_secret;
111:
112: /**
113: * clientRandom
114: */
115: byte[] clientRandom;
116:
117: /**
118: * serverRandom
119: */
120: byte[] serverRandom;
121:
122: /**
123: * True if this entity is considered the server
124: */
125: boolean isServer = false;
126:
127: /**
128: * Creates SSLSession implementation
129: * @param cipher_suite
130: * @param sr
131: */
132: public SSLSessionImpl(CipherSuite cipher_suite, SecureRandom sr) {
133: creationTime = System.currentTimeMillis();
134: lastAccessedTime = creationTime;
135: if (cipher_suite == null) {
136: this .cipherSuite = CipherSuite.TLS_NULL_WITH_NULL_NULL;
137: id = new byte[0];
138: isServer = false;
139: } else {
140: this .cipherSuite = cipher_suite;
141: id = new byte[32];
142: sr.nextBytes(id);
143: long time = new java.util.Date().getTime() / 1000;
144: id[28] = (byte) ((time & 0xFF000000) >>> 24);
145: id[29] = (byte) ((time & 0xFF0000) >>> 16);
146: id[30] = (byte) ((time & 0xFF00) >>> 8);
147: id[31] = (byte) (time & 0xFF);
148: isServer = true;
149: }
150:
151: }
152:
153: /**
154: * Creates SSLSession implementation
155: * @param sr
156: */
157: public SSLSessionImpl(SecureRandom sr) {
158: this (null, sr);
159: }
160:
161: private SSLSessionImpl() {
162: }
163:
164: /**
165: * @see javax.net.ssl.SSLSession.getApplicationBufferSize()
166: */
167: public int getApplicationBufferSize() {
168: return SSLRecordProtocol.MAX_DATA_LENGTH;
169: }
170:
171: /**
172: * @see javax.net.ssl.SSLSession.getCipherSuite()
173: */
174: public String getCipherSuite() {
175: return cipherSuite.getName();
176: }
177:
178: /**
179: * @see javax.net.ssl.SSLSession.getCreationTime()
180: */
181: public long getCreationTime() {
182: return creationTime;
183: }
184:
185: /**
186: * @see javax.net.ssl.SSLSession.getId()
187: */
188: public byte[] getId() {
189: return id;
190: }
191:
192: /**
193: * @see javax.net.ssl.SSLSession.getLastAccessedTime()
194: */
195: public long getLastAccessedTime() {
196: return lastAccessedTime;
197: }
198:
199: /**
200: * @see javax.net.ssl.SSLSession.getLocalCertificates()
201: */
202: public Certificate[] getLocalCertificates() {
203: return localCertificates;
204: }
205:
206: /**
207: * @see javax.net.ssl.SSLSession.getLocalPrincipal()
208: */
209: public Principal getLocalPrincipal() {
210: if (localCertificates != null && localCertificates.length > 0) {
211: return localCertificates[0].getSubjectX500Principal();
212: } else {
213: return null;
214: }
215: }
216:
217: /**
218: * @see javax.net.ssl.SSLSession.getPacketBufferSize()
219: */
220: public int getPacketBufferSize() {
221: return SSLRecordProtocol.MAX_SSL_PACKET_SIZE;
222: }
223:
224: /**
225: * @see javax.net.ssl.SSLSession.getPeerCertificateChain()
226: */
227: public javax.security.cert.X509Certificate[] getPeerCertificateChain()
228: throws SSLPeerUnverifiedException {
229: if (peerCertificates == null) {
230: throw new SSLPeerUnverifiedException("No peer certificate");
231: }
232: javax.security.cert.X509Certificate[] certs = new javax.security.cert.X509Certificate[peerCertificates.length];
233: for (int i = 0; i < certs.length; i++) {
234: try {
235: certs[i] = javax.security.cert.X509Certificate
236: .getInstance(peerCertificates[i].getEncoded());
237: } catch (javax.security.cert.CertificateException e) {
238: } catch (CertificateEncodingException e) {
239: }
240: }
241: return certs;
242: }
243:
244: /**
245: * @see javax.net.ssl.SSLSession.getPeerCertificates()
246: */
247: public Certificate[] getPeerCertificates()
248: throws SSLPeerUnverifiedException {
249: if (peerCertificates == null) {
250: throw new SSLPeerUnverifiedException("No peer certificate");
251: }
252: return peerCertificates;
253: }
254:
255: /**
256: * @see javax.net.ssl.SSLSession.getPeerHost()
257: */
258: public String getPeerHost() {
259: return peerHost;
260: }
261:
262: /**
263: * @see javax.net.ssl.SSLSession.getPeerPort()
264: */
265: public int getPeerPort() {
266: return peerPort;
267: }
268:
269: /**
270: * @see javax.net.ssl.SSLSession.getPeerPrincipal()
271: */
272: public Principal getPeerPrincipal()
273: throws SSLPeerUnverifiedException {
274: if (peerCertificates == null) {
275: throw new SSLPeerUnverifiedException("No peer certificate");
276: }
277: return peerCertificates[0].getSubjectX500Principal();
278: }
279:
280: /**
281: * @see javax.net.ssl.SSLSession.getProtocol()
282: */
283: public String getProtocol() {
284: return protocol.name;
285: }
286:
287: /**
288: * @see javax.net.ssl.SSLSession.getSessionContext()
289: */
290: public SSLSessionContext getSessionContext() {
291: SecurityManager sm = System.getSecurityManager();
292: if (sm != null) {
293: sm
294: .checkPermission(new SSLPermission(
295: "getSSLSessionContext"));
296: }
297: return context;
298: }
299:
300: /**
301: * @see javax.net.ssl.SSLSession.getValue(String name)
302: */
303: public Object getValue(String name) {
304: if (name == null) {
305: throw new IllegalArgumentException("Parameter is null");
306: }
307: return values.get(name, AccessController.getContext());
308: }
309:
310: /**
311: * @see javax.net.ssl.SSLSession.getValueNames()
312: */
313: public String[] getValueNames() {
314: Vector v = new Vector();
315: AccessControlContext current = AccessController.getContext();
316: AccessControlContext cont;
317: for (Iterator it = values.entrySet().iterator(); it.hasNext();) {
318: TwoKeyHashMap.Entry entry = (TwoKeyHashMap.Entry) it.next();
319: cont = (AccessControlContext) entry.getKey2();
320: if ((current == null && cont == null)
321: || (current != null && current.equals(cont))) {
322: v.add(entry.getKey1());
323: }
324: }
325: return (String[]) v.toArray(new String[0]);
326: }
327:
328: /**
329: * @see javax.net.ssl.SSLSession.invalidate()
330: */
331: public void invalidate() {
332: isValid = false;
333: }
334:
335: /**
336: * @see javax.net.ssl.SSLSession.isValid()
337: */
338: public boolean isValid() {
339: if (isValid
340: && context != null
341: && context.getSessionTimeout() != 0
342: && lastAccessedTime + context.getSessionTimeout() > System
343: .currentTimeMillis()) {
344: isValid = false;
345: }
346: return isValid;
347: }
348:
349: /**
350: * @see javax.net.ssl.SSLSession.putValue(String name, Object value)
351: */
352: public void putValue(String name, Object value) {
353: if (name == null || value == null) {
354: throw new IllegalArgumentException("Parameter is null");
355: }
356: Object old = values.put(name, AccessController.getContext(),
357: value);
358: if (value instanceof SSLSessionBindingListener) {
359: ((SSLSessionBindingListener) value)
360: .valueBound(new SSLSessionBindingEvent(this , name));
361: }
362: if (old != null && old instanceof SSLSessionBindingListener) {
363: ((SSLSessionBindingListener) old)
364: .valueUnbound(new SSLSessionBindingEvent(this , name));
365: }
366:
367: }
368:
369: /**
370: * @see javax.net.ssl.SSLSession.removeValue(String name)
371: */
372: public void removeValue(String name) {
373: if (name == null) {
374: throw new IllegalArgumentException("Parameter is null");
375: }
376: values.remove(name, AccessController.getContext());
377:
378: }
379:
380: public Object clone() {
381: SSLSessionImpl ses = new SSLSessionImpl();
382: ses.id = this .id;
383: ses.creationTime = this .creationTime;
384: ses.lastAccessedTime = this .lastAccessedTime;
385: ses.isValid = this .isValid;
386: ses.cipherSuite = this .cipherSuite;
387: ses.localCertificates = this .localCertificates;
388: ses.peerCertificates = this .peerCertificates;
389: ses.master_secret = this .master_secret;
390: ses.clientRandom = this .clientRandom;
391: ses.serverRandom = this .serverRandom;
392: ses.peerHost = this .peerHost;
393: ses.peerPort = this .peerPort;
394: ses.isServer = this .isServer;
395: ses.context = this .context;
396: ses.protocol = this .protocol;
397: ses.values = this .values;
398: return ses;
399: }
400:
401: /**
402: * Sets the address of the peer
403: * @param peerHost
404: * @param peerPort
405: */
406: void setPeer(String peerHost, int peerPort) {
407: this.peerHost = peerHost;
408: this.peerPort = peerPort;
409: }
410: }
|