1/* 2 * Copyright (c) 2000, 2001, 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 26package org.ietf.jgss; 27 28import java.net.InetAddress; 29import java.util.Arrays; 30 31/** 32 * This class encapsulates the concept of caller-provided channel 33 * binding information. Channel bindings are used to strengthen the 34 * quality with which peer entity authentication is provided during 35 * context establishment. They enable the GSS-API callers to bind the 36 * establishment of the security context to relevant characteristics 37 * like addresses or to application specific data.<p> 38 * 39 * The caller initiating the security context must determine the 40 * appropriate channel binding values to set in the GSSContext object. 41 * The acceptor must provide an identical binding in order to validate 42 * that received tokens possess correct channel-related characteristics.<p> 43 * 44 * Use of channel bindings is optional in GSS-API. ChannelBinding can be 45 * set for the {@link GSSContext GSSContext} using the {@link 46 * GSSContext#setChannelBinding(ChannelBinding) setChannelBinding} method 47 * before the first call to {@link GSSContext#initSecContext(byte[], int, int) 48 * initSecContext} or {@link GSSContext#acceptSecContext(byte[], int, int) 49 * acceptSecContext} has been performed. Unless the <code>setChannelBinding</code> 50 * method has been used to set the ChannelBinding for a GSSContext object, 51 * <code>null</code> ChannelBinding will be assumed. <p> 52 * 53 * Conceptually, the GSS-API concatenates the initiator and acceptor 54 * address information, and the application supplied byte array to form an 55 * octet string. The mechanism calculates a MIC over this octet string and 56 * binds the MIC to the context establishment token emitted by 57 * <code>initSecContext</code> method of the <code>GSSContext</code> 58 * interface. The same bindings are set by the context acceptor for its 59 * <code>GSSContext</code> object and during processing of the 60 * <code>acceptSecContext</code> method a MIC is calculated in the same 61 * way. The calculated MIC is compared with that found in the token, and if 62 * the MICs differ, accept will throw a <code>GSSException</code> with the 63 * major code set to {@link GSSException#BAD_BINDINGS BAD_BINDINGS}, and 64 * the context will not be established. Some mechanisms may include the 65 * actual channel binding data in the token (rather than just a MIC); 66 * applications should therefore not use confidential data as 67 * channel-binding components.<p> 68 * 69 * Individual mechanisms may impose additional constraints on addresses 70 * that may appear in channel bindings. For example, a mechanism may 71 * verify that the initiator address field of the channel binding 72 * contains the correct network address of the host system. Portable 73 * applications should therefore ensure that they either provide correct 74 * information for the address fields, or omit setting of the addressing 75 * information. 76 * 77 * @author Mayank Upadhyay 78 * @since 1.4 79 */ 80public class ChannelBinding { 81 82 private InetAddress initiator; 83 private InetAddress acceptor; 84 private byte[] appData; 85 86 /** 87 * Create a ChannelBinding object with user supplied address information 88 * and data. <code>null</code> values can be used for any fields which the 89 * application does not want to specify. 90 * 91 * @param initAddr the address of the context initiator. 92 * <code>null</code> value can be supplied to indicate that the 93 * application does not want to set this value. 94 * @param acceptAddr the address of the context 95 * acceptor. <code>null</code> value can be supplied to indicate that 96 * the application does not want to set this value. 97 * @param appData application supplied data to be used as part of the 98 * channel bindings. <code>null</code> value can be supplied to 99 * indicate that the application does not want to set this value. 100 */ 101 public ChannelBinding(InetAddress initAddr, InetAddress acceptAddr, 102 byte[] appData) { 103 104 initiator = initAddr; 105 acceptor = acceptAddr; 106 107 if (appData != null) { 108 this.appData = new byte[appData.length]; 109 java.lang.System.arraycopy(appData, 0, this.appData, 0, 110 appData.length); 111 } 112 } 113 114 /** 115 * Creates a ChannelBinding object without any addressing information. 116 * 117 * @param appData application supplied data to be used as part of the 118 * channel bindings. 119 */ 120 public ChannelBinding(byte[] appData) { 121 this(null, null, appData); 122 } 123 124 /** 125 * Get the initiator's address for this channel binding. 126 * 127 * @return the initiator's address. <code>null</code> is returned if 128 * the address has not been set. 129 */ 130 public InetAddress getInitiatorAddress() { 131 return initiator; 132 } 133 134 /** 135 * Get the acceptor's address for this channel binding. 136 * 137 * @return the acceptor's address. null is returned if the address has 138 * not been set. 139 */ 140 public InetAddress getAcceptorAddress() { 141 return acceptor; 142 } 143 144 /** 145 * Get the application specified data for this channel binding. 146 * 147 * @return the application data being used as part of the 148 * ChannelBinding. <code>null</code> is returned if no application data 149 * has been specified for the channel binding. 150 */ 151 public byte[] getApplicationData() { 152 153 if (appData == null) { 154 return null; 155 } 156 157 byte[] retVal = new byte[appData.length]; 158 System.arraycopy(appData, 0, retVal, 0, appData.length); 159 return retVal; 160 } 161 162 /** 163 * Compares two instances of ChannelBinding. 164 * 165 * @param obj another ChannelBinding to compare this one with 166 * @return true if the two ChannelBinding's contain 167 * the same values for the initiator and acceptor addresses and the 168 * application data. 169 */ 170 public boolean equals(Object obj) { 171 172 if (this == obj) 173 return true; 174 175 if (! (obj instanceof ChannelBinding)) 176 return false; 177 178 ChannelBinding cb = (ChannelBinding) obj; 179 180 if ((initiator != null && cb.initiator == null) || 181 (initiator == null && cb.initiator != null)) 182 return false; 183 184 if (initiator != null && !initiator.equals(cb.initiator)) 185 return false; 186 187 if ((acceptor != null && cb.acceptor == null) || 188 (acceptor == null && cb.acceptor != null)) 189 return false; 190 191 if (acceptor != null && !acceptor.equals(cb.acceptor)) 192 return false; 193 194 return Arrays.equals(appData, cb.appData); 195 } 196 197 /** 198 * Returns a hashcode value for this ChannelBinding object. 199 * 200 * @return a hashCode value 201 */ 202 public int hashCode() { 203 if (initiator != null) 204 return initiator.hashCode(); 205 else if (acceptor != null) 206 return acceptor.hashCode(); 207 else if (appData != null) 208 return new String(appData).hashCode(); 209 else 210 return 1; 211 } 212} 213