5776631 [rkeene@sledge /home/rkeene/archive/floydssh/ssh]$ cat -n SshPacket1.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 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
5776632 [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