832 lines · 26.6 KB · Java
RawDownload
     * @throws SSLPeerUnverifiedException if the peer's identity has not     *          been verified     */    public Principal getPeerPrincipal()                throws SSLPeerUnverifiedException    {        if ((cipherSuite.keyExchange == K_KRB5) ||            (cipherSuite.keyExchange == K_KRB5_EXPORT)) {            if (peerPrincipal == null) {                throw new SSLPeerUnverifiedException("peer not authenticated");            } else {                // Eliminate dependency on KerberosPrincipal                return peerPrincipal;            }        }        if (peerCerts == null) {            throw new SSLPeerUnverifiedException("peer not authenticated");        }        return peerCerts[0].getSubjectX500Principal();    }     /**     * Returns the principal that was sent to the peer during handshaking.     *     * @return the principal sent to the peer. Returns an X500Principal     * of the end-entity certificate for X509-based cipher suites, and     * Principal for Kerberos cipher suites. If no principal was     * sent, then null is returned.     */    public Principal getLocalPrincipal() {         if ((cipherSuite.keyExchange == K_KRB5) ||            (cipherSuite.keyExchange == K_KRB5_EXPORT)) {                // Eliminate dependency on KerberosPrincipal                return (localPrincipal == null ? null : localPrincipal);        }        return (localCerts == null ? null :                localCerts[0].getSubjectX500Principal());    }     /**     * Returns the time this session was created.     */    public long getCreationTime() {        return creationTime;    }     /**     * Returns the last time this session was used to initialize     * a connection.     */    public long getLastAccessedTime() {        return (lastUsedTime != 0) ? lastUsedTime : creationTime;    }     void setLastAccessedTime(long time) {        lastUsedTime = time;    }      /**     * Returns the network address of the session's peer.  This     * implementation does not insist that connections between     * different ports on the same host must necessarily belong     * to different sessions, though that is of course allowed.     */    public InetAddress getPeerAddress() {        try {            return InetAddress.getByName(host);        } catch (java.net.UnknownHostException e) {            return null;        }    }     public String getPeerHost() {        return host;    }     /**     * Need to provide the port info for caching sessions based on     * host and port. Accessed by SSLSessionContextImpl     */    public int getPeerPort() {        return port;    }     void setContext(SSLSessionContextImpl ctx) {        if (context == null) {            context = ctx;        }    }     /**     * Invalidate a session.  Active connections may still exist, but     * no connections will be able to rejoin this session.     */    synchronized public void invalidate() {        //        // Can't invalidate the NULL session -- this would be        // attempted when we get a handshaking error on a brand        // new connection, with no "real" session yet.        //        if (this == nullSession) {            return;        }        invalidated = true;        if (debug != null && Debug.isOn("session")) {            System.out.println("%% Invalidated:  " + this);        }        if (context != null) {            context.remove(sessionId);            context = null;        }    }     /*     * Table of application-specific session data indexed by an application     * key and the calling security context. This is important since     * sessions can be shared across different protection domains.     */    private Hashtable<SecureKey, Object> table = new Hashtable<>();     /**     * Assigns a session value.  Session change events are given if     * appropriate, to any original value as well as the new value.     */    public void putValue(String key, Object value) {        if ((key == null) || (value == null)) {            throw new IllegalArgumentException("arguments can not be null");        }         SecureKey secureKey = new SecureKey(key);        Object oldValue = table.put(secureKey, value);         if (oldValue instanceof SSLSessionBindingListener) {            SSLSessionBindingEvent e;             e = new SSLSessionBindingEvent(this, key);            ((SSLSessionBindingListener)oldValue).valueUnbound(e);        }        if (value instanceof SSLSessionBindingListener) {            SSLSessionBindingEvent e;             e = new SSLSessionBindingEvent(this, key);            ((SSLSessionBindingListener)value).valueBound(e);        }    }      /**     * Returns the specified session value.     */    public Object getValue(String key) {        if (key == null) {            throw new IllegalArgumentException("argument can not be null");        }         SecureKey secureKey = new SecureKey(key);        return table.get(secureKey);    }      /**     * Removes the specified session value, delivering a session changed     * event as appropriate.     */    public void removeValue(String key) {        if (key == null) {            throw new IllegalArgumentException("argument can not be null");        }         SecureKey secureKey = new SecureKey(key);        Object value = table.remove(secureKey);         if (value instanceof SSLSessionBindingListener) {            SSLSessionBindingEvent e;             e = new SSLSessionBindingEvent(this, key);            ((SSLSessionBindingListener)value).valueUnbound(e);        }    }      /**     * Lists the names of the session values.     */    public String[] getValueNames() {        Enumeration<SecureKey> e;        Vector<Object> v = new Vector<>();        SecureKey key;        Object securityCtx = SecureKey.getCurrentSecurityContext();         for (e = table.keys(); e.hasMoreElements(); ) {            key = e.nextElement();             if (securityCtx.equals(key.getSecurityContext())) {                v.addElement(key.getAppKey());            }        }        String[] names = new String[v.size()];        v.copyInto(names);         return names;    }     /**     * Use large packet sizes now or follow RFC 2246 packet sizes (2^14)     * until changed.     *     * In the TLS specification (section 6.2.1, RFC2246), it is not     * recommended that the plaintext has more than 2^14 bytes.     * However, some TLS implementations violate the specification.     * This is a workaround for interoperability with these stacks.     *     * Application could accept large fragments up to 2^15 bytes by     * setting the system property jsse.SSLEngine.acceptLargeFragments     * to "true".     */    private boolean acceptLargeFragments =        Debug.getBooleanProperty("jsse.SSLEngine.acceptLargeFragments", false);     /**     * Expand the buffer size of both SSL/TLS network packet and     * application data.     */    protected synchronized void expandBufferSizes() {        acceptLargeFragments = true;    }     /**     * Gets the current size of the largest SSL/TLS packet that is expected     * when using this session.     */    public synchronized int getPacketBufferSize() {        return acceptLargeFragments ?                Record.maxLargeRecordSize : Record.maxRecordSize;    }     /**     * Gets the current size of the largest application data that is     * expected when using this session.     */    public synchronized int getApplicationBufferSize() {        return getPacketBufferSize() - Record.headerSize;    }     /**     * Gets an array of supported signature algorithms that the local side is     * willing to verify.     */    public String[] getLocalSupportedSignatureAlgorithms() {        if (localSupportedSignAlgs != null) {            return localSupportedSignAlgs.clone();        }         return new String[0];    }     /**     * Gets an array of supported signature algorithms that the peer is     * able to verify.     */    public String[] getPeerSupportedSignatureAlgorithms() {        if (peerSupportedSignAlgs != null) {            return peerSupportedSignAlgs.clone();        }         return new String[0];    }     /** Returns a string representation of this SSL session */    public String toString() {        return "[Session-" + sessionCount            + ", " + getCipherSuite()            + "]";    }     /**     * When SSL sessions are finalized, all values bound to     * them are removed.     */    public void finalize() {        String[] names = getValueNames();        for (int i = 0; i < names.length; i++) {            removeValue(names[i]);        }    }}  /** * This "struct" class serves as a Hash Key that combines an * application-specific key and a security context. */class SecureKey {    private static Object       nullObject = new Object();    private Object        appKey;    private Object      securityCtx;     static Object getCurrentSecurityContext() {        SecurityManager sm = System.getSecurityManager();        Object context = null;         if (sm != null)            context = sm.getSecurityContext();        if (context == null)            context = nullObject;        return context;    }     SecureKey(Object key) {        this.appKey = key;        this.securityCtx = getCurrentSecurityContext();    }     Object getAppKey() {        return appKey;    }     Object getSecurityContext() {        return securityCtx;    }     public int hashCode() {        return appKey.hashCode() ^ securityCtx.hashCode();    }     public boolean equals(Object o) {        return o instanceof SecureKey && ((SecureKey)o).appKey.equals(appKey)                        && ((SecureKey)o).securityCtx.equals(securityCtx);    }}

Lines 501–832 of 832. Previous lines