5776633 [rkeene@sledge /home/rkeene/archive/floydssh/ssh]$ cat -n SshPacket2.java
  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 }
5776634 [rkeene@sledge /home/rkeene/archive/floydssh/ssh]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2004-03-06 22:44:06