00001 using System;
00002
00003 namespace Tamir.SharpSsh.jsch
00004 {
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 public class DHG1 : KeyExchange
00036 {
00037
00038 internal static byte[] g=new byte[]{ 2 };
00039 internal static byte[] p=new byte[]{
00040 (byte)0x00,
00041 (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
00042 (byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
00043 (byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
00044 (byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
00045 (byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
00046 (byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
00047 (byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
00048 (byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
00049 (byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
00050 (byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
00051 (byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
00052 (byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
00053 (byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
00054 (byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
00055 (byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE6,(byte)0x53,(byte)0x81,
00056 (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
00057 };
00058
00059 internal const int SSH_MSG_KEXDH_INIT= 30;
00060 internal const int SSH_MSG_KEXDH_REPLY= 31;
00061
00062 internal const int RSA=0;
00063 internal const int DSS=1;
00064 private int type=0;
00065
00066 private int state;
00067
00068 internal DH dh;
00069
00070
00071
00072
00073
00074 internal byte[] V_S;
00075 internal byte[] V_C;
00076 internal byte[] I_S;
00077 internal byte[] I_C;
00078
00079
00080
00081 internal byte[] e;
00082
00083 private Buffer buf;
00084 private Packet packet;
00085
00086 public override void init(Session session,
00087 byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C)
00088 {
00089 this.session=session;
00090 this.V_S=V_S;
00091 this.V_C=V_C;
00092 this.I_S=I_S;
00093 this.I_C=I_C;
00094
00095
00096
00097 try
00098 {
00099 Type t=Type.GetType(session.getConfig("sha-1"));
00100 sha=(HASH)(Activator.CreateInstance(t));
00101 sha.init();
00102 }
00103 catch(Exception ee)
00104 {
00105 Console.WriteLine(ee);
00106 }
00107
00108 buf=new Buffer();
00109 packet=new Packet(buf);
00110
00111 try
00112 {
00113 Type t=Type.GetType(session.getConfig("dh"));
00114 dh=(DH)(Activator.CreateInstance(t));
00115 dh.init();
00116 }
00117 catch(Exception ee)
00118 {
00119 throw ee;
00120 }
00121
00122 dh.setP(p);
00123 dh.setG(g);
00124
00125
00126
00127
00128
00129
00130 e=dh.getE();
00131
00132 packet.reset();
00133 buf.putByte((byte)SSH_MSG_KEXDH_INIT);
00134 buf.putMPInt(e);
00135 session.write(packet);
00136
00137 state=SSH_MSG_KEXDH_REPLY;
00138 }
00139
00140 public override bool next(Buffer _buf)
00141 {
00142 int i,j;
00143 bool result = false;
00144 switch(state)
00145 {
00146 case SSH_MSG_KEXDH_REPLY:
00147
00148
00149
00150
00151
00152 j=_buf.getInt();
00153 j=_buf.getByte();
00154 j=_buf.getByte();
00155 if(j!=31)
00156 {
00157 Console.WriteLine("type: must be 31 "+j);
00158 result = false;
00159 break;
00160 }
00161
00162 K_S=_buf.getString();
00163
00164
00165
00166
00167
00168
00169
00170 byte[] f=_buf.getMPInt();
00171 byte[] sig_of_H=_buf.getString();
00172
00173
00174
00175
00176
00177
00178
00179
00180 dh.setF(f);
00181 K=dh.getK();
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 buf.reset();
00196 buf.putString(V_C); buf.putString(V_S);
00197 buf.putString(I_C); buf.putString(I_S);
00198 buf.putString(K_S);
00199 buf.putMPInt(e); buf.putMPInt(f);
00200 buf.putMPInt(K);
00201 byte[] foo=new byte[buf.getLength()];
00202 buf.getByte(foo);
00203 sha.update(foo, 0, foo.Length);
00204 H=sha.digest();
00205
00206
00207 i=0;
00208 j=0;
00209 j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00210 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00211 String alg=Util.getString(K_S, i, j);
00212 i+=j;
00213
00214 result=false;
00215
00216 if(alg.Equals("ssh-rsa"))
00217 {
00218 byte[] tmp;
00219 byte[] ee;
00220 byte[] n;
00221
00222 type=RSA;
00223
00224 j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00225 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00226 tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j;
00227 ee=tmp;
00228 j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00229 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00230 tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j;
00231 n=tmp;
00232
00233
00234
00235
00236 SignatureRSA sig=null;
00237 try
00238 {
00239 Type t=Type.GetType(session.getConfig("signature.rsa"));
00240 sig=(SignatureRSA)(Activator.CreateInstance(t));
00241 sig.init();
00242 }
00243 catch(Exception eee)
00244 {
00245 Console.WriteLine(eee);
00246 }
00247
00248 sig.setPubKey(ee, n);
00249 sig.update(H);
00250 result=sig.verify(sig_of_H);
00251
00252 }
00253 else if(alg.Equals("ssh-dss"))
00254 {
00255 byte[] q=null;
00256 byte[] tmp;
00257 byte[] p;
00258 byte[] g;
00259
00260 type=DSS;
00261
00262 j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00263 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00264 tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j;
00265 p=tmp;
00266 j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00267 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00268 tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j;
00269 q=tmp;
00270 j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00271 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00272 tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j;
00273 g=tmp;
00274 j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00275 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00276 tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j;
00277 f=tmp;
00278
00279
00280 SignatureDSA sig=null;
00281 try
00282 {
00283 Type t=Type.GetType(session.getConfig("signature.dss"));
00284 sig=(SignatureDSA)(Activator.CreateInstance(t));
00285 sig.init();
00286 }
00287 catch(Exception ee)
00288 {
00289 Console.WriteLine(ee);
00290 }
00291 sig.setPubKey(f, p, q, g);
00292 sig.update(H);
00293 result=sig.verify(sig_of_H);
00294 }
00295 else
00296 {
00297 Console.WriteLine("unknow alg");
00298 }
00299 state=STATE_END;
00300 break;
00301 }
00302 return result;
00303 }
00304
00305 public override String getKeyType()
00306 {
00307 if(type==DSS) return "DSA";
00308 return "RSA";
00309 }
00310
00311 public override int getState(){return state; }
00312 }
00313
00314 }