1 /* 2 * This file is part of "The Java Telnet Application". 3 * 4 * (c) Matthias L. Jugel, Marcus Meißner 1996-2002. All Rights Reserved. 5 * The file was changed by Radek Polak to work as midlet in MIDP 1.0 6 * 7 * Please visit http://javatelnet.org/ for updates and contact. 8 * 9 * --LICENSE NOTICE-- 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License 12 * as published by the Free Software Foundation; either version 2 13 * of the License, or (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 * --LICENSE NOTICE-- 24 */ 25 package ssh; 26 27 /** 28 * @author Marcus Meissner 29 * @version $Id: SshPacket1.java,v 1.3 2002/10/26 07:15:59 leo Exp $ 30 */ 31 public class SshPacket1 extends SshPacket { 32 private final static boolean debug = false; 33 34 //SSH_RECEIVE_PACKET 35 private byte[] packet_length_array = new byte[4]; 36 private int packet_length = 0; 37 private byte[] padding = null; 38 private byte[] crc_array = new byte[4]; 39 private byte[] block = null; 40 private byte[] encryptedBlock = null; // encrypted part (Padding + Type + Data + Check) 41 private byte[] decryptedBlock = null; // decrypted part (Padding + Type + Data + Check) 42 43 private SshCrypto crypto = null; 44 45 public SshPacket1(SshCrypto _crypto) { 46 /* receiving packet */ 47 position = 0; 48 phase_packet = PHASE_packet_length; 49 crypto = _crypto; 50 } 51 52 public SshPacket1(byte newType) { 53 setType(newType); 54 } 55 56 /** 57 * Return the mp-int at the position offset in the data 58 * First 2 bytes are the number of bits in the integer, msb first 59 * (for example, the value 0x00012345 would have 17 bits). The 60 * value zero has zero bits. It is permissible that the number of 61 * bits be larger than the real number of bits. 62 * The number of bits is followed by (bits + 7) / 8 bytes of binary 63 * data, msb first, giving the value of the integer. 64 */ 65 66 public byte[] getMpInt() { 67 return getBytes((getInt16() + 7) / 8); 68 } 69 70 public void putMpInt(BigInteger bi) { 71 byte[] mpbytes = bi.toByteArray(), xbytes; 72 int i; 73 for (i = 0; (i < mpbytes.length) && (mpbytes[i] == 0); i++) /* EMPTY */ ; 74 xbytes = new byte[mpbytes.length - i]; 75 System.arraycopy(mpbytes, i, xbytes, 0, mpbytes.length - i); 76 putInt16(xbytes.length * 8); 77 putBytes(xbytes); 78 } 79 80 byte[] getPayLoad(SshCrypto crypto) { 81 byte[] data = getData(); 82 83 //packet length 84 if (data != null) 85 packet_length = data.length + 5; 86 else 87 packet_length = 5; 88 packet_length_array[3] = (byte) (packet_length & 0xff); 89 packet_length_array[2] = (byte) ((packet_length >> 8) & 0xff); 90 packet_length_array[1] = (byte) ((packet_length >> 16) & 0xff); 91 packet_length_array[0] = (byte) ((packet_length >> 24) & 0xff); 92 93 //padding 94 padding = new byte[(8 - (packet_length % 8))]; 95 if (crypto == null) { 96 for (int i = 0; i < padding.length; i++) 97 padding[i] = 0; 98 } else { 99 for (int i = 0; i < padding.length; i++) 100 padding[i] = SshMisc.getNotZeroRandomByte(); 101 } 102 103 //Compute the crc of [ Padding, Packet type, Data ] 104 105 block = new byte[packet_length + padding.length]; 106 System.arraycopy(padding, 0, block, 0, padding.length); 107 int offset = padding.length; 108 block[offset++] = getType(); 109 if (packet_length > 5) { 110 System.arraycopy(data, 0, block, offset, data.length); 111 offset += data.length; 112 } 113 114 long crc = SshMisc.crc32(block, offset); 115 crc_array[3] = (byte) (crc & 0xff); 116 crc_array[2] = (byte) ((crc >> 8) & 0xff); 117 crc_array[1] = (byte) ((crc >> 16) & 0xff); 118 crc_array[0] = (byte) ((crc >> 24) & 0xff); 119 System.arraycopy(crc_array, 0, block, offset, 4); 120 121 //encrypt 122 if (crypto != null) 123 block = crypto.encrypt(block); 124 byte[] full = new byte[block.length + 4]; 125 System.arraycopy(packet_length_array, 0, full, 0, 4); 126 System.arraycopy(block, 0, full, 4, block.length); 127 return full; 128 }; 129 130 private int position = 0; 131 private int phase_packet = 0; 132 private final int PHASE_packet_length = 0; 133 private final int PHASE_block = 1; 134 135 public byte[] addPayload(byte[] buff) { 136 int boffset = 0; 137 byte newbuf[] = null; 138 139 while (boffset < buff.length) { 140 switch (phase_packet) { 141 142 // 4 bytes 143 // Packet length: 32 bit unsigned integer 144 // gives the length of the packet, not including the length field 145 // and padding. maximum is 262144 bytes. 146 147 case PHASE_packet_length: 148 packet_length_array[position++] = buff[boffset++]; 149 if (position >= 4) { 150 packet_length = 151 (packet_length_array[3] & 0xff) + 152 ((packet_length_array[2] & 0xff) << 8) + 153 ((packet_length_array[1] & 0xff) << 16) + 154 ((packet_length_array[0] & 0xff) << 24); 155 position = 0; 156 phase_packet++; 157 block = new byte[8 * (packet_length / 8 + 1)]; 158 } 159 break; //switch (phase_packet) 160 161 //8*(packet_length/8 +1) bytes 162 163 case PHASE_block: 164 165 if (block.length > position) { 166 if (boffset < buff.length) { 167 int amount = buff.length - boffset; 168 if (amount > block.length - position) 169 amount = block.length - position; 170 System.arraycopy(buff, boffset, block, position, amount); 171 boffset += amount; 172 position += amount; 173 } 174 } 175 176 if (position == block.length) { //the block is complete 177 if (buff.length > boffset) { //there is more than 1 packet in buff 178 newbuf = new byte[buff.length - boffset]; 179 System.arraycopy(buff, boffset, newbuf, 0, buff.length - boffset); 180 } 181 int blockOffset = 0; 182 //padding 183 int padding_length = (int) (8 - (packet_length % 8)); 184 padding = new byte[padding_length]; 185 186 if (crypto != null) 187 decryptedBlock = crypto.decrypt(block); 188 else 189 decryptedBlock = block; 190 191 if (decryptedBlock.length != padding_length + packet_length) 192 System.out.println("???"); 193 194 for (int i = 0; i < padding.length; i++) 195 padding[i] = decryptedBlock[blockOffset++]; 196 197 //packet type 198 setType(decryptedBlock[blockOffset++]); 199 200 byte[] data; 201 //data 202 if (packet_length > 5) { 203 data = new byte[packet_length - 5]; 204 System.arraycopy(decryptedBlock, blockOffset, data, 0, packet_length - 5); 205 blockOffset += packet_length - 5; 206 } else 207 data = null; 208 putData(data); 209 //crc 210 for (int i = 0; i < crc_array.length; i++) 211 crc_array[i] = decryptedBlock[blockOffset++]; 212 if (!checkCrc()) 213 System.err.println("SshPacket1: CRC wrong in received packet!"); 214 215 return newbuf; 216 } 217 break; 218 } 219 } 220 return null; 221 }; 222 223 private boolean checkCrc() { 224 byte[] crc_arrayCheck = new byte[4]; 225 long crcCheck; 226 227 crcCheck = SshMisc.crc32(decryptedBlock, decryptedBlock.length - 4); 228 crc_arrayCheck[3] = (byte) (crcCheck & 0xff); 229 crc_arrayCheck[2] = (byte) ((crcCheck >> 8) & 0xff); 230 crc_arrayCheck[1] = (byte) ((crcCheck >> 16) & 0xff); 231 crc_arrayCheck[0] = (byte) ((crcCheck >> 24) & 0xff); 232 233 if (debug) { 234 System.err.println(crc_arrayCheck[3] + " == " + crc_array[3]); 235 System.err.println(crc_arrayCheck[2] + " == " + crc_array[2]); 236 System.err.println(crc_arrayCheck[1] + " == " + crc_array[1]); 237 System.err.println(crc_arrayCheck[0] + " == " + crc_array[0]); 238 } 239 if (crc_arrayCheck[3] != crc_array[3]) return false; 240 if (crc_arrayCheck[2] != crc_array[2]) return false; 241 if (crc_arrayCheck[1] != crc_array[1]) return false; 242 if (crc_arrayCheck[0] != crc_array[0]) return false; 243 return true; 244 } 245 } //class |