Home | History | Annotate | Download | only in jsse
      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