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 26 package ssh; 27 28 29 import java.io.IOException; 30 31 /** 32 * @author Marcus Meissner 33 * @version $Id: SshPacket2.java,v 1.3 2002/10/26 07:15:59 leo Exp $ 34 */ 35 public class SshPacket2 extends SshPacket { 36 37 private final static boolean debug = true; 38 39 //SSH_RECEIVE_PACKET 40 private byte[] packet_length_array = new byte[5]; // 4 bytes 41 private int packet_length = 0; // 32-bit sign int 42 private int padlen = 0; // packet length 1 byte unsigned 43 private byte[] crc_array = new byte[4]; // 32-bit crc 44 45 46 private int position = 0; 47 private int phase_packet = 0; 48 private final int PHASE_packet_length = 0; 49 private final int PHASE_block = 1; 50 51 private SshCrypto crypto = null; 52 53 public SshPacket2(SshCrypto _crypto) { 54 /* receiving packet */ 55 position = 0; 56 phase_packet = PHASE_packet_length; 57 crypto = _crypto; 58 } 59 60 public SshPacket2(byte newType) { 61 setType(newType); 62 } 63 64 /** 65 * Return the mp-int at the position offset in the data 66 * First 4 bytes are the number of bytes in the integer, msb first 67 * (for example, the value 0x00012345 would have 17 bits). The 68 * value zero has zero bits. It is permissible that the number of 69 * bits be larger than the real number of bits. 70 * The number of bits is followed by (bits + 7) / 8 bytes of binary 71 * data, msb first, giving the value of the integer. 72 */ 73 74 public BigInteger getMpInt() { 75 return new BigInteger(getBytes(getInt32())); 76 } 77 78 public void putMpInt(BigInteger bi) { 79 byte[] mpbytes = bi.toByteArray(), xbytes; 80 int i; 81 82 for (i = 0; (i < mpbytes.length) && ( mpbytes[i] == 0 ) ; i++) /* EMPTY */ ; 83 xbytes = new byte[mpbytes.length - i]; 84 System.arraycopy(mpbytes,i,xbytes,0,mpbytes.length - i); 85 86 putInt32(mpbytes.length - i); 87 putBytes(xbytes); 88 } 89 90 public byte[] getPayLoad(SshCrypto xcrypt, long seqnr) 91 throws IOException { 92 byte[] data = getData(); 93 94 int blocksize = 8; 95 96 // crypted data is: 97 // packet length [ payloadlen + padlen + type + data ] 98 packet_length = 4 + 1 + 1; 99 if (data!=null) 100 packet_length += data.length; 101 102 // pad it up to full blocksize. 103 // If not crypto, zeroes, otherwise random. 104 // (zeros because we do not want to tell the attacker the state of our 105 // random generator) 106 int padlen = blocksize - (packet_length % blocksize); 107 if (padlen < 4) padlen += blocksize; 108 109 byte[] padding = new byte[padlen]; 110 System.out.println("packet length is "+packet_length+", padlen is "+padlen); 111 if (xcrypt == null) 112 for(int i=0; i<padlen; i++) padding[i] = 0; 113 else 114 for(int i=0; i<padlen; i++) padding[i] = SshMisc.getNotZeroRandomByte(); 115 116 // [ packetlength, padlength, padding, packet type, data ] 117 byte[] block = new byte[ packet_length + padlen ]; 118 119 int xlen = padlen + packet_length - 4; 120 block[3] = (byte) (xlen & 0xff); 121 block[2] = (byte) ((xlen>>8) & 0xff); 122 block[1] = (byte) ((xlen>>16) & 0xff); 123 block[0] = (byte) ((xlen>>24) & 0xff); 124 125 block[4] = (byte)padlen; 126 block[5] = getType(); 127 System.arraycopy(data,0,block,6,data.length); 128 System.arraycopy(padding,0,block,6+data.length,padlen); 129 130 byte[] md5sum; 131 if (xcrypt != null) { 132 MD5 md5 = new MD5(); 133 byte[] seqint = new byte[4]; 134 135 seqint[0] = (byte)((seqnr >> 24) & 0xff); 136 seqint[1] = (byte)((seqnr >> 16) & 0xff); 137 seqint[2] = (byte)((seqnr >> 8) & 0xff); 138 seqint[3] = (byte)((seqnr ) & 0xff); 139 md5.update(seqint,0,4); 140 md5.update(block,0,block.length); 141 md5sum = md5.digest(); 142 } else { 143 md5sum = new byte[0]; 144 } 145 146 if (xcrypt != null) 147 block = xcrypt.encrypt(block); 148 149 byte[] sendblock = new byte[block.length + md5sum.length]; 150 System.arraycopy(block,0,sendblock,0,block.length); 151 System.arraycopy(md5sum,0,sendblock,block.length,md5sum.length); 152 return sendblock; 153 }; 154 155 private byte block[]; 156 157 public byte[] addPayload(byte buff[]) { 158 int boffset = 0; 159 byte b; 160 byte[] newbuf = null; 161 int hmaclen = 0; 162 163 if (crypto!=null) hmaclen = 16; 164 165 System.out.println("addPayload2 "+buff.length); 166 167 /* 168 * Note: The whole packet is encrypted, except for the MAC. 169 * 170 * (So I have to rewrite it again). 171 */ 172 173 while(boffset < buff.length) { 174 switch (phase_packet) { 175 // 4 bytes 176 // Packet length: 32 bit unsigned integer 177 // gives the length of the packet, not including the length field 178 // and padding. maximum is 262144 bytes. 179 180 case PHASE_packet_length: 181 packet_length_array[position++] = buff[boffset++]; 182 if (position==5) { 183 packet_length = 184 (packet_length_array[3]&0xff) + 185 ((packet_length_array[2]&0xff)<<8) + 186 ((packet_length_array[1]&0xff)<<16) + 187 ((packet_length_array[0]&0xff)<<24); 188 padlen = packet_length_array[4]; 189 position=0; 190 System.out.println("SSH2: packet length "+packet_length); 191 System.out.println("SSH2: padlen "+padlen); 192 packet_length += hmaclen; /* len(md5) */ 193 block = new byte[packet_length-1]; /* padlen already done */ 194 phase_packet++; 195 } 196 break; //switch (phase_packet) 197 198 //8*(packet_length/8 +1) bytes 199 200 case PHASE_block : 201 if (position < block.length) { 202 int amount = buff.length - boffset; 203 if (amount > 0) { 204 if (amount > block.length - position) 205 amount = block.length - position; 206 System.arraycopy(buff,boffset,block,position,amount); 207 boffset += amount; 208 position += amount; 209 } 210 } 211 if (position==block.length) { //the block is complete 212 if (buff.length>boffset) { 213 newbuf = new byte[buff.length-boffset]; 214 System.arraycopy(buff,boffset,newbuf,0,buff.length-boffset); 215 } 216 byte[] decryptedBlock = new byte[block.length - hmaclen]; 217 byte[] data; 218 packet_length -= hmaclen; 219 220 System.arraycopy(block,0,decryptedBlock,0,block.length-hmaclen); 221 222 if (crypto != null) 223 decryptedBlock = crypto.decrypt(decryptedBlock); 224 225 for (int i = 0; i < decryptedBlock.length; i++) 226 System.out.print(" "+decryptedBlock[i]); 227 System.out.println(""); 228 229 setType(decryptedBlock[0]); 230 System.err.println("Packet type: "+getType()); 231 System.err.println("Packet len: "+packet_length); 232 233 //data 234 if(packet_length > padlen+1+1) { 235 data = new byte[packet_length-1-padlen-1]; 236 System.arraycopy(decryptedBlock,1,data,0,data.length); 237 putData(data); 238 } else { 239 putData(null); 240 } 241 /* MAC! */ 242 return newbuf; 243 } 244 break; 245 } 246 } 247 return null; 248 }; 249 /* 250 251 private boolean checkCrc(){ 252 byte[] crc_arrayCheck = new byte[4]; 253 long crcCheck; 254 255 crcCheck = SshMisc.crc32(decryptedBlock, decryptedBlock.length-4); 256 crc_arrayCheck[3] = (byte) (crcCheck & 0xff); 257 crc_arrayCheck[2] = (byte) ((crcCheck>>8) & 0xff); 258 crc_arrayCheck[1] = (byte) ((crcCheck>>16) & 0xff); 259 crc_arrayCheck[0] = (byte) ((crcCheck>>24) & 0xff); 260 261 if(debug) { 262 System.err.println(crc_arrayCheck[3]+" == "+crc_array[3]); 263 System.err.println(crc_arrayCheck[2]+" == "+crc_array[2]); 264 System.err.println(crc_arrayCheck[1]+" == "+crc_array[1]); 265 System.err.println(crc_arrayCheck[0]+" == "+crc_array[0]); 266 } 267 if (crc_arrayCheck[3] != crc_array[3]) return false; 268 if (crc_arrayCheck[2] != crc_array[2]) return false; 269 if (crc_arrayCheck[1] != crc_array[1]) return false; 270 if (crc_arrayCheck[0] != crc_array[0]) return false; 271 return true; 272 } 273 */ 274 } |