Path: blob/master/src/java.security.jgss/share/classes/org/ietf/jgss/ChannelBinding.java
41155 views
/*1* Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package org.ietf.jgss;2627import java.net.InetAddress;28import java.util.Arrays;2930/**31* This class encapsulates the concept of caller-provided channel32* binding information. Channel bindings are used to strengthen the33* quality with which peer entity authentication is provided during34* context establishment. They enable the GSS-API callers to bind the35* establishment of the security context to relevant characteristics36* like addresses or to application specific data.<p>37*38* The caller initiating the security context must determine the39* appropriate channel binding values to set in the GSSContext object.40* The acceptor must provide an identical binding in order to validate41* that received tokens possess correct channel-related characteristics.<p>42*43* Use of channel bindings is optional in GSS-API. ChannelBinding can be44* set for the {@link GSSContext GSSContext} using the {@link45* GSSContext#setChannelBinding(ChannelBinding) setChannelBinding} method46* before the first call to {@link GSSContext#initSecContext(byte[], int, int)47* initSecContext} or {@link GSSContext#acceptSecContext(byte[], int, int)48* acceptSecContext} has been performed. Unless the <code>setChannelBinding</code>49* method has been used to set the ChannelBinding for a GSSContext object,50* <code>null</code> ChannelBinding will be assumed. <p>51*52* Conceptually, the GSS-API concatenates the initiator and acceptor53* address information, and the application supplied byte array to form an54* octet string. The mechanism calculates a MIC over this octet string and55* binds the MIC to the context establishment token emitted by56* <code>initSecContext</code> method of the <code>GSSContext</code>57* interface. The same bindings are set by the context acceptor for its58* <code>GSSContext</code> object and during processing of the59* <code>acceptSecContext</code> method a MIC is calculated in the same60* way. The calculated MIC is compared with that found in the token, and if61* the MICs differ, accept will throw a <code>GSSException</code> with the62* major code set to {@link GSSException#BAD_BINDINGS BAD_BINDINGS}, and63* the context will not be established. Some mechanisms may include the64* actual channel binding data in the token (rather than just a MIC);65* applications should therefore not use confidential data as66* channel-binding components.<p>67*68* Individual mechanisms may impose additional constraints on addresses69* that may appear in channel bindings. For example, a mechanism may70* verify that the initiator address field of the channel binding71* contains the correct network address of the host system. Portable72* applications should therefore ensure that they either provide correct73* information for the address fields, or omit setting of the addressing74* information.75*76* @author Mayank Upadhyay77* @since 1.478*/79public class ChannelBinding {8081private InetAddress initiator;82private InetAddress acceptor;83private byte[] appData;8485/**86* Create a ChannelBinding object with user supplied address information87* and data. <code>null</code> values can be used for any fields which the88* application does not want to specify.89*90* @param initAddr the address of the context initiator.91* <code>null</code> value can be supplied to indicate that the92* application does not want to set this value.93* @param acceptAddr the address of the context94* acceptor. <code>null</code> value can be supplied to indicate that95* the application does not want to set this value.96* @param appData application supplied data to be used as part of the97* channel bindings. <code>null</code> value can be supplied to98* indicate that the application does not want to set this value.99*/100public ChannelBinding(InetAddress initAddr, InetAddress acceptAddr,101byte[] appData) {102103initiator = initAddr;104acceptor = acceptAddr;105106if (appData != null) {107this.appData = new byte[appData.length];108java.lang.System.arraycopy(appData, 0, this.appData, 0,109appData.length);110}111}112113/**114* Creates a ChannelBinding object without any addressing information.115*116* @param appData application supplied data to be used as part of the117* channel bindings.118*/119public ChannelBinding(byte[] appData) {120this(null, null, appData);121}122123/**124* Get the initiator's address for this channel binding.125*126* @return the initiator's address. <code>null</code> is returned if127* the address has not been set.128*/129public InetAddress getInitiatorAddress() {130return initiator;131}132133/**134* Get the acceptor's address for this channel binding.135*136* @return the acceptor's address. null is returned if the address has137* not been set.138*/139public InetAddress getAcceptorAddress() {140return acceptor;141}142143/**144* Get the application specified data for this channel binding.145*146* @return the application data being used as part of the147* ChannelBinding. <code>null</code> is returned if no application data148* has been specified for the channel binding.149*/150public byte[] getApplicationData() {151152if (appData == null) {153return null;154}155156byte[] retVal = new byte[appData.length];157System.arraycopy(appData, 0, retVal, 0, appData.length);158return retVal;159}160161/**162* Compares two instances of ChannelBinding.163*164* @param obj another ChannelBinding to compare this one with165* @return true if the two ChannelBinding's contain166* the same values for the initiator and acceptor addresses and the167* application data.168*/169public boolean equals(Object obj) {170171if (this == obj)172return true;173174if (! (obj instanceof ChannelBinding))175return false;176177ChannelBinding cb = (ChannelBinding) obj;178179if ((initiator != null && cb.initiator == null) ||180(initiator == null && cb.initiator != null))181return false;182183if (initiator != null && !initiator.equals(cb.initiator))184return false;185186if ((acceptor != null && cb.acceptor == null) ||187(acceptor == null && cb.acceptor != null))188return false;189190if (acceptor != null && !acceptor.equals(cb.acceptor))191return false;192193return Arrays.equals(appData, cb.appData);194}195196/**197* Returns a hashcode value for this ChannelBinding object.198*199* @return a hashCode value200*/201public int hashCode() {202if (initiator != null)203return initiator.hashCode();204else if (acceptor != null)205return acceptor.hashCode();206else if (appData != null)207return new String(appData).hashCode();208else209return 1;210}211}212213214