1/* 2 * Copyright (c) 2005, 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 sun.security.jgss; 27 28import java.io.InputStream; 29import java.io.OutputStream; 30import java.io.IOException; 31import java.io.EOFException; 32import sun.security.util.*; 33 34/** 35 * Utilities for processing GSS Tokens. 36 * 37 */ 38 39public abstract class GSSToken { 40 41 /** 42 * Copies an integer value to a byte array in little endian form. 43 * @param value the integer value to write 44 * @param array the byte array into which the integer must be copied. It 45 * is assumed that the array will be large enough to hold the 4 bytes of 46 * the integer. 47 */ 48 public static final void writeLittleEndian(int value, byte[] array) { 49 writeLittleEndian(value, array, 0); 50 } 51 52 /** 53 * Copies an integer value to a byte array in little endian form. 54 * @param value the integer value to write 55 * @param array the byte array into which the integer must be copied. It 56 * is assumed that the array will be large enough to hold the 4 bytes of 57 * the integer. 58 * @param pos the position at which to start writing 59 */ 60 public static final void writeLittleEndian(int value, byte[] array, 61 int pos) { 62 array[pos++] = (byte)(value); 63 array[pos++] = (byte)((value>>>8)); 64 array[pos++] = (byte)((value>>>16)); 65 array[pos++] = (byte)((value>>>24)); 66 } 67 68 public static final void writeBigEndian(int value, byte[] array) { 69 writeBigEndian(value, array, 0); 70 } 71 72 public static final void writeBigEndian(int value, byte[] array, 73 int pos) { 74 array[pos++] = (byte)((value>>>24)); 75 array[pos++] = (byte)((value>>>16)); 76 array[pos++] = (byte)((value>>>8)); 77 array[pos++] = (byte)(value); 78 } 79 80 /** 81 * Reads an integer value from a byte array in little endian form. This 82 * method allows the reading of two byte values as well as four bytes 83 * values both of which are needed in the Kerberos v5 GSS-API mechanism. 84 * 85 * @param data the array containing the bytes of the integer value 86 * @param pos the offset in the array 87 * @param size the number of bytes to read from the array. 88 * @return the integer value 89 */ 90 public static final int readLittleEndian(byte[] data, int pos, int size) { 91 int retVal = 0; 92 int shifter = 0; 93 while (size > 0) { 94 retVal += (data[pos] & 0xff) << shifter; 95 shifter += 8; 96 pos++; 97 size--; 98 } 99 return retVal; 100 } 101 102 public static final int readBigEndian(byte[] data, int pos, int size) { 103 int retVal = 0; 104 int shifter = (size-1)*8; 105 while (size > 0) { 106 retVal += (data[pos] & 0xff) << shifter; 107 shifter -= 8; 108 pos++; 109 size--; 110 } 111 return retVal; 112 } 113 114 /** 115 * Writes a two byte integer value to a OutputStream. 116 * 117 * @param val the integer value. It will lose the high-order two bytes. 118 * @param os the OutputStream to write to 119 * @throws IOException if an error occurs while writing to the OutputStream 120 */ 121 public static final void writeInt(int val, OutputStream os) 122 throws IOException { 123 os.write(val>>>8); 124 os.write(val); 125 } 126 127 /** 128 * Writes a two byte integer value to a byte array. 129 * 130 * @param val the integer value. It will lose the high-order two bytes. 131 * @param dest the byte array to write to 132 * @param pos the offset to start writing to 133 */ 134 public static final int writeInt(int val, byte[] dest, int pos) { 135 dest[pos++] = (byte)(val>>>8); 136 dest[pos++] = (byte)val; 137 return pos; 138 } 139 140 /** 141 * Reads a two byte integer value from an InputStream. 142 * 143 * @param is the InputStream to read from 144 * @return the integer value 145 * @throws IOException if some errors occurs while reading the integer 146 * bytes. 147 */ 148 public static final int readInt(InputStream is) throws IOException { 149 return (((0xFF & is.read()) << 8) 150 | (0xFF & is.read())); 151 } 152 153 /** 154 * Reads a two byte integer value from a byte array. 155 * 156 * @param src the byte arra to read from 157 * @param pos the offset to start reading from 158 * @return the integer value 159 */ 160 public static final int readInt(byte[] src, int pos) { 161 return ((0xFF & src[pos])<<8 | (0xFF & src[pos+1])); 162 } 163 164 /** 165 * Blocks till the required number of bytes have been read from the 166 * input stream. 167 * 168 * @param is the InputStream to read from 169 * @param buffer the buffer to store the bytes into 170 * @throws EOFException if EOF is reached before all bytes are 171 * read. 172 * @throws IOException is an error occurs while reading 173 */ 174 public static final void readFully(InputStream is, byte[] buffer) 175 throws IOException { 176 readFully(is, buffer, 0, buffer.length); 177 } 178 179 /** 180 * Blocks till the required number of bytes have been read from the 181 * input stream. 182 * 183 * @param is the InputStream to read from 184 * @param buffer the buffer to store the bytes into 185 * @param offset the offset to start storing at 186 * @param len the number of bytes to read 187 * @throws EOFException if EOF is reached before all bytes are 188 * read. 189 * @throws IOException is an error occurs while reading 190 */ 191 public static final void readFully(InputStream is, 192 byte[] buffer, int offset, int len) 193 throws IOException { 194 int temp; 195 while (len > 0) { 196 temp = is.read(buffer, offset, len); 197 if (temp == -1) 198 throw new EOFException("Cannot read all " 199 + len 200 + " bytes needed to form this token!"); 201 offset += temp; 202 len -= temp; 203 } 204 } 205 206 public static final void debug(String str) { 207 System.err.print(str); 208 } 209 210 public static final String getHexBytes(byte[] bytes) { 211 return getHexBytes(bytes, 0, bytes.length); 212 } 213 214 public static final String getHexBytes(byte[] bytes, int len) { 215 return getHexBytes(bytes, 0, len); 216 } 217 218 public static final String getHexBytes(byte[] bytes, int pos, int len) { 219 StringBuilder sb = new StringBuilder(); 220 for (int i = pos; i < (pos+len); i++) { 221 int b1 = (bytes[i]>>4) & 0x0f; 222 int b2 = bytes[i] & 0x0f; 223 224 sb.append(Integer.toHexString(b1)); 225 sb.append(Integer.toHexString(b2)); 226 sb.append(' '); 227 } 228 return sb.toString(); 229 } 230 231} 232