1 /*
   2  * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.net.ssl;
  27 
  28 import java.util.EventObject;
  29 import java.security.cert.Certificate;
  30 import java.security.Principal;
  31 import java.security.cert.X509Certificate;
  32 
  33 /**
  34  * This event indicates that an SSL handshake completed on a given
  35  * SSL connection.  All of the core information about that handshake's
  36  * result is captured through an "SSLSession" object.  As a convenience,
  37  * this event class provides direct access to some important session
  38  * attributes.
  39  *
  40  * <P> The source of this event is the SSLSocket on which handshaking
  41  * just completed.
  42  *
  43  * @see SSLSocket
  44  * @see HandshakeCompletedListener
  45  * @see SSLSession
  46  *
  47  * @since 1.4
  48  * @author David Brownell
  49  */
  50 public class HandshakeCompletedEvent extends EventObject
  51 {
  52     private static final long serialVersionUID = 7914963744257769778L;
  53 
  54     private transient SSLSession session;
  55 
  56     /**
  57      * Constructs a new HandshakeCompletedEvent.
  58      *
  59      * @param source the source of the event
  60      * @param s the SSLSession this event is associated with
  61      */
  62     public HandshakeCompletedEvent(Object source, SSLSession s)
  63     {
  64         super(source);
  65         session = s;
  66     }
  67 
  68 
  69     /**
  70      * Returns the session that triggered this event.
  71      *
  72      * @return the <code>SSLSession</code> for this handshake
  73      */
  74     public SSLSession getSession()
  75     {
  76         return session;
  77     }
  78 
  79 
  80     /**
  81      * Returns the cipher suite in use by the session which was produced
  82      * by the handshake.  (This is a convenience method for
  83      * getting the ciphersuite from the SSLsession.)
  84      *
  85      * @return the name of the cipher suite negotiated during this session.
  86      */
  87     public String getCipherSuite()
  88     {
  89         return session.getCipherSuite();
  90     }
  91 
  92 
  93     /**
  94      * Returns the certificate(s) that were sent to the peer during
  95      * handshaking.
  96      * Note: This method is useful only when using certificate-based
  97      * cipher suites.
  98      *
  99      * When multiple certificates are available for use in a
 100      * handshake, the implementation chooses what it considers the
 101      * "best" certificate chain available, and transmits that to
 102      * the other side.  This method allows the caller to know
 103      * which certificate chain was actually used.
 104      *
 105      * @return an ordered array of certificates, with the local
 106      *          certificate first followed by any
 107      *          certificate authorities.  If no certificates were sent,
 108      *          then null is returned.
 109      * @see #getLocalPrincipal()
 110      */
 111     public java.security.cert.Certificate [] getLocalCertificates()
 112     {
 113         return session.getLocalCertificates();
 114     }
 115 
 116 
 117     /**
 118      * Returns the identity of the peer which was established as part
 119      * of defining the session.
 120      * Note: This method can be used only when using certificate-based
 121      * cipher suites; using it with non-certificate-based cipher suites,
 122      * such as Kerberos, will throw an SSLPeerUnverifiedException.
 123      * <P>
 124      * Note: The returned value may not be a valid certificate chain
 125      * and should not be relied on for trust decisions.
 126      *
 127      * @return an ordered array of the peer certificates,
 128      *          with the peer's own certificate first followed by
 129      *          any certificate authorities.
 130      * @exception SSLPeerUnverifiedException if the peer is not verified.
 131      * @see #getPeerPrincipal()
 132      */
 133     public java.security.cert.Certificate [] getPeerCertificates()
 134             throws SSLPeerUnverifiedException
 135     {
 136         return session.getPeerCertificates();
 137     }
 138 
 139 
 140     /**
 141      * Returns the identity of the peer which was identified as part
 142      * of defining the session.
 143      * Note: This method can be used only when using certificate-based
 144      * cipher suites; using it with non-certificate-based cipher suites,
 145      * such as Kerberos, will throw an SSLPeerUnverifiedException.
 146      * <P>
 147      * Note: The returned value may not be a valid certificate chain
 148      * and should not be relied on for trust decisions.
 149      *
 150      * <p><em>Note: this method exists for compatibility with previous
 151      * releases. New applications should use
 152      * {@link #getPeerCertificates} instead.</em></p>
 153      *
 154      * @return an ordered array of peer X.509 certificates,
 155      *          with the peer's own certificate first followed by any
 156      *          certificate authorities.  (The certificates are in
 157      *          the original JSSE
 158      *          {@link javax.security.cert.X509Certificate} format).
 159      * @exception SSLPeerUnverifiedException if the peer is not verified.
 160      * @see #getPeerPrincipal()
 161      * @deprecated The {@link #getPeerCertificates()} method that returns an
 162      *               array of {@code java.security.cert.Certificate} should
 163      *               be used instead.
 164      */
 165     @Deprecated(since="9")
 166     public javax.security.cert.X509Certificate [] getPeerCertificateChain()
 167             throws SSLPeerUnverifiedException
 168     {
 169         return session.getPeerCertificateChain();
 170     }
 171 
 172     /**
 173      * Returns the identity of the peer which was established as part of
 174      * defining the session.
 175      *
 176      * @return the peer's principal. Returns an X500Principal of the
 177      * end-entity certiticate for X509-based cipher suites, and
 178      * KerberosPrincipal for Kerberos cipher suites.
 179      *
 180      * @throws SSLPeerUnverifiedException if the peer's identity has not
 181      *          been verified
 182      *
 183      * @see #getPeerCertificates()
 184      * @see #getLocalPrincipal()
 185      *
 186      * @since 1.5
 187      */
 188     public Principal getPeerPrincipal()
 189             throws SSLPeerUnverifiedException
 190     {
 191         Principal principal;
 192         try {
 193             principal = session.getPeerPrincipal();
 194         } catch (AbstractMethodError e) {
 195             // if the provider does not support it, fallback to peer certs.
 196             // return the X500Principal of the end-entity cert.
 197             Certificate[] certs = getPeerCertificates();
 198             principal = ((X509Certificate)certs[0]).getSubjectX500Principal();
 199         }
 200         return principal;
 201     }
 202 
 203     /**
 204      * Returns the principal that was sent to the peer during handshaking.
 205      *
 206      * @return the principal sent to the peer. Returns an X500Principal
 207      * of the end-entity certificate for X509-based cipher suites, and
 208      * KerberosPrincipal for Kerberos cipher suites. If no principal was
 209      * sent, then null is returned.
 210      *
 211      * @see #getLocalCertificates()
 212      * @see #getPeerPrincipal()
 213      *
 214      * @since 1.5
 215      */
 216     public Principal getLocalPrincipal()
 217     {
 218         Principal principal;
 219         try {
 220             principal = session.getLocalPrincipal();
 221         } catch (AbstractMethodError e) {
 222             principal = null;
 223             // if the provider does not support it, fallback to local certs.
 224             // return the X500Principal of the end-entity cert.
 225             Certificate[] certs = getLocalCertificates();
 226             if (certs != null) {
 227                 principal =
 228                         ((X509Certificate)certs[0]).getSubjectX500Principal();
 229             }
 230         }
 231         return principal;
 232     }
 233 
 234     /**
 235      * Returns the socket which is the source of this event.
 236      * (This is a convenience function, to let applications
 237      * write code without type casts.)
 238      *
 239      * @return the socket on which the connection was made.
 240      */
 241     public SSLSocket getSocket()
 242     {
 243         return (SSLSocket) getSource();
 244     }
 245 }