/* |
|
* Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved. |
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
* |
|
* This code is free software; you can redistribute it and/or modify it |
|
* under the terms of the GNU General Public License version 2 only, as |
|
* published by the Free Software Foundation. Oracle designates this |
|
* particular file as subject to the "Classpath" exception as provided |
|
* by Oracle in the LICENSE file that accompanied this code. |
|
* |
|
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
* version 2 for more details (a copy is included in the LICENSE file that |
|
* accompanied this code). |
|
* |
|
* You should have received a copy of the GNU General Public License version |
|
* 2 along with this work; if not, write to the Free Software Foundation, |
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
* |
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
* or visit www.oracle.com if you need additional information or have any |
|
* questions. |
|
*/ |
|
package org.ietf.jgss; |
|
import java.net.InetAddress; |
|
import java.util.Arrays; |
|
/** |
|
* This class encapsulates the concept of caller-provided channel |
|
* binding information. Channel bindings are used to strengthen the |
|
* quality with which peer entity authentication is provided during |
|
* context establishment. They enable the GSS-API callers to bind the |
|
* establishment of the security context to relevant characteristics |
|
* like addresses or to application specific data.<p> |
|
* |
|
* The caller initiating the security context must determine the |
|
* appropriate channel binding values to set in the GSSContext object. |
|
* The acceptor must provide an identical binding in order to validate |
|
* that received tokens possess correct channel-related characteristics.<p> |
|
* |
|
* Use of channel bindings is optional in GSS-API. ChannelBinding can be |
|
* set for the {@link GSSContext GSSContext} using the {@link |
|
* GSSContext#setChannelBinding(ChannelBinding) setChannelBinding} method |
|
* before the first call to {@link GSSContext#initSecContext(byte[], int, int) |
|
* initSecContext} or {@link GSSContext#acceptSecContext(byte[], int, int) |
|
* acceptSecContext} has been performed. Unless the <code>setChannelBinding</code> |
|
* method has been used to set the ChannelBinding for a GSSContext object, |
|
* <code>null</code> ChannelBinding will be assumed. <p> |
|
* |
|
* Conceptually, the GSS-API concatenates the initiator and acceptor |
|
* address information, and the application supplied byte array to form an |
|
* octet string. The mechanism calculates a MIC over this octet string and |
|
* binds the MIC to the context establishment token emitted by |
|
* <code>initSecContext</code> method of the <code>GSSContext</code> |
|
* interface. The same bindings are set by the context acceptor for its |
|
* <code>GSSContext</code> object and during processing of the |
|
* <code>acceptSecContext</code> method a MIC is calculated in the same |
|
* way. The calculated MIC is compared with that found in the token, and if |
|
* the MICs differ, accept will throw a <code>GSSException</code> with the |
|
* major code set to {@link GSSException#BAD_BINDINGS BAD_BINDINGS}, and |
|
* the context will not be established. Some mechanisms may include the |
|
* actual channel binding data in the token (rather than just a MIC); |
|
* applications should therefore not use confidential data as |
|
* channel-binding components.<p> |
|
* |
|
* Individual mechanisms may impose additional constraints on addresses |
|
* that may appear in channel bindings. For example, a mechanism may |
|
* verify that the initiator address field of the channel binding |
|
* contains the correct network address of the host system. Portable |
|
* applications should therefore ensure that they either provide correct |
|
* information for the address fields, or omit setting of the addressing |
|
* information. |
|
* |
|
* @author Mayank Upadhyay |
|
* @since 1.4 |
|
*/ |
|
public class ChannelBinding { |
|
private InetAddress initiator; |
|
private InetAddress acceptor; |
|
private byte[] appData; |
|
/** |
|
* Create a ChannelBinding object with user supplied address information |
|
* and data. <code>null</code> values can be used for any fields which the |
|
* application does not want to specify. |
|
* |
|
* @param initAddr the address of the context initiator. |
|
* <code>null</code> value can be supplied to indicate that the |
|
* application does not want to set this value. |
|
* @param acceptAddr the address of the context |
|
* acceptor. <code>null</code> value can be supplied to indicate that |
|
* the application does not want to set this value. |
|
* @param appData application supplied data to be used as part of the |
|
* channel bindings. <code>null</code> value can be supplied to |
|
* indicate that the application does not want to set this value. |
|
*/ |
|
public ChannelBinding(InetAddress initAddr, InetAddress acceptAddr, |
|
byte[] appData) { |
|
initiator = initAddr; |
|
acceptor = acceptAddr; |
|
if (appData != null) { |
|
this.appData = new byte[appData.length]; |
|
java.lang.System.arraycopy(appData, 0, this.appData, 0, |
|
appData.length); |
|
} |
|
} |
|
/** |
|
* Creates a ChannelBinding object without any addressing information. |
|
* |
|
* @param appData application supplied data to be used as part of the |
|
* channel bindings. |
|
*/ |
|
public ChannelBinding(byte[] appData) { |
|
this(null, null, appData); |
|
} |
|
/** |
|
* Get the initiator's address for this channel binding. |
|
* |
|
* @return the initiator's address. <code>null</code> is returned if |
|
* the address has not been set. |
|
*/ |
|
public InetAddress getInitiatorAddress() { |
|
return initiator; |
|
} |
|
/** |
|
* Get the acceptor's address for this channel binding. |
|
* |
|
* @return the acceptor's address. null is returned if the address has |
|
* not been set. |
|
*/ |
|
public InetAddress getAcceptorAddress() { |
|
return acceptor; |
|
} |
|
/** |
|
* Get the application specified data for this channel binding. |
|
* |
|
* @return the application data being used as part of the |
|
* ChannelBinding. <code>null</code> is returned if no application data |
|
* has been specified for the channel binding. |
|
*/ |
|
public byte[] getApplicationData() { |
|
if (appData == null) { |
|
return null; |
|
} |
|
byte[] retVal = new byte[appData.length]; |
|
System.arraycopy(appData, 0, retVal, 0, appData.length); |
|
return retVal; |
|
} |
|
/** |
|
* Compares two instances of ChannelBinding. |
|
* |
|
* @param obj another ChannelBinding to compare this one with |
|
* @return true if the two ChannelBinding's contain |
|
* the same values for the initiator and acceptor addresses and the |
|
* application data. |
|
*/ |
|
public boolean equals(Object obj) { |
|
if (this == obj) |
|
return true; |
|
if (! (obj instanceof ChannelBinding)) |
|
return false; |
|
ChannelBinding cb = (ChannelBinding) obj; |
|
if ((initiator != null && cb.initiator == null) || |
|
(initiator == null && cb.initiator != null)) |
|
return false; |
|
if (initiator != null && !initiator.equals(cb.initiator)) |
|
return false; |
|
if ((acceptor != null && cb.acceptor == null) || |
|
(acceptor == null && cb.acceptor != null)) |
|
return false; |
|
if (acceptor != null && !acceptor.equals(cb.acceptor)) |
|
return false; |
|
return Arrays.equals(appData, cb.appData); |
|
} |
|
/** |
|
* Returns a hashcode value for this ChannelBinding object. |
|
* |
|
* @return a hashCode value |
|
*/ |
|
public int hashCode() { |
|
if (initiator != null) |
|
return initiator.hashCode(); |
|
else if (acceptor != null) |
|
return acceptor.hashCode(); |
|
else if (appData != null) |
|
return new String(appData).hashCode(); |
|
else |
|
return 1; |
|
} |
|
} |