/* * 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; }}
/*
* 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;
}
}