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 DHGEX : KeyExchange
00036 {
00037
00038 internal const int SSH_MSG_KEX_DH_GEX_GROUP= 31;
00039 internal const int SSH_MSG_KEX_DH_GEX_INIT= 32;
00040 internal const int SSH_MSG_KEX_DH_GEX_REPLY= 33;
00041
00042 internal static int min=1024;
00043
00044
00045 internal static int preferred=1024;
00046 internal static int max=1024;
00047
00048
00049
00050
00051 internal const int RSA=0;
00052 internal const int DSS=1;
00053 private int type=0;
00054
00055 private int state;
00056
00057
00058 internal DH dh;
00059
00060 internal byte[] V_S;
00061 internal byte[] V_C;
00062 internal byte[] I_S;
00063 internal byte[] I_C;
00064
00065 private Buffer buf;
00066 private Packet packet;
00067
00068 private byte[] p;
00069 private byte[] g;
00070 private byte[] e;
00071
00072
00073 public override void init(Session session,
00074 byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C)
00075 {
00076 this.session=session;
00077 this.V_S=V_S;
00078 this.V_C=V_C;
00079 this.I_S=I_S;
00080 this.I_C=I_C;
00081
00082
00083
00084
00085 try
00086 {
00087 Type t=Type.GetType(session.getConfig("sha-1"));
00088 sha=(HASH)(Activator.CreateInstance(t));
00089 sha.init();
00090 }
00091 catch(Exception e)
00092 {
00093 Console.WriteLine(e);
00094 }
00095
00096 buf=new Buffer();
00097 packet=new Packet(buf);
00098
00099 try
00100 {
00101 Type t=Type.GetType(session.getConfig("dh"));
00102 dh=(DH)(Activator.CreateInstance(t));
00103 dh.init();
00104 }
00105 catch(Exception e)
00106 {
00107 throw e;
00108 }
00109
00110 packet.reset();
00111 buf.putByte((byte)0x22);
00112 buf.putInt(min);
00113 buf.putInt(preferred);
00114 buf.putInt(max);
00115 session.write(packet);
00116
00117 state=SSH_MSG_KEX_DH_GEX_GROUP;
00118 }
00119
00120 public override bool next(Buffer _buf)
00121 {
00122 int i,j;
00123 bool result=false;
00124 switch(state)
00125 {
00126 case SSH_MSG_KEX_DH_GEX_GROUP:
00127
00128
00129
00130 _buf.getInt();
00131 _buf.getByte();
00132 j=_buf.getByte();
00133 if(j!=31)
00134 {
00135 Console.WriteLine("type: must be 31 "+j);
00136 result = false;
00137 }
00138
00139 p=_buf.getMPInt();
00140 g=_buf.getMPInt();
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 dh.setP(p);
00151 dh.setG(g);
00152
00153
00154
00155
00156
00157
00158 e=dh.getE();
00159
00160 packet.reset();
00161 buf.putByte((byte)0x20);
00162 buf.putMPInt(e);
00163 session.write(packet);
00164
00165 state=SSH_MSG_KEX_DH_GEX_REPLY;
00166 result = true;
00167 break;
00168
00169 case SSH_MSG_KEX_DH_GEX_REPLY:
00170
00171
00172
00173
00174
00175 j=_buf.getInt();
00176 j=_buf.getByte();
00177 j=_buf.getByte();
00178 if(j!=33)
00179 {
00180 Console.WriteLine("type: must be 33 "+j);
00181 result = false;
00182 }
00183
00184 K_S=_buf.getString();
00185
00186
00187
00188
00189
00190
00191
00192
00193 byte[] f=_buf.getMPInt();
00194 byte[] sig_of_H=_buf.getString();
00195
00196 dh.setF(f);
00197 K=dh.getK();
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 buf.reset();
00218 buf.putString(V_C); buf.putString(V_S);
00219 buf.putString(I_C); buf.putString(I_S);
00220 buf.putString(K_S);
00221 buf.putInt(min); buf.putInt(preferred); buf.putInt(max);
00222 buf.putMPInt(p); buf.putMPInt(g); buf.putMPInt(e); buf.putMPInt(f);
00223 buf.putMPInt(K);
00224
00225 byte[] foo=new byte[buf.getLength()];
00226 buf.getByte(foo);
00227 sha.update(foo, 0, foo.Length);
00228
00229 H=sha.digest();
00230
00231
00232
00233 i=0;
00234 j=0;
00235 j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00236 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00237 String alg=Util.getString(K_S, i, j);
00238 i+=j;
00239
00240
00241 if(alg.Equals("ssh-rsa"))
00242 {
00243 byte[] tmp;
00244 byte[] ee;
00245 byte[] n;
00246
00247 type=RSA;
00248
00249 j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00250 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00251 tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j;
00252 ee=tmp;
00253 j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00254 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00255 tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j;
00256 n=tmp;
00257
00258
00259
00260
00261 SignatureRSA sig=null;
00262 try
00263 {
00264 Type t=Type.GetType(session.getConfig("signature.rsa"));
00265 sig=(SignatureRSA)(Activator.CreateInstance(t));
00266 sig.init();
00267 }
00268 catch(Exception eee)
00269 {
00270 Console.WriteLine(eee);
00271 }
00272
00273 sig.setPubKey(ee, n);
00274 sig.update(H);
00275 result=sig.verify(sig_of_H);
00276 }
00277 else if(alg.Equals("ssh-dss"))
00278 {
00279 byte[] q=null;
00280 byte[] tmp;
00281
00282 type=DSS;
00283
00284 j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00285 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00286 tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j;
00287 p=tmp;
00288 j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00289 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00290 tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j;
00291 q=tmp;
00292 j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00293 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00294 tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j;
00295 g=tmp;
00296 j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00297 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00298 tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j;
00299 f=tmp;
00300
00301
00302
00303
00304 SignatureDSA sig=null;
00305 try
00306 {
00307 Type t=Type.GetType(session.getConfig("signature.dss"));
00308 sig=(SignatureDSA)(Activator.CreateInstance(t));
00309 sig.init();
00310 }
00311 catch(Exception ee)
00312 {
00313 Console.WriteLine(ee);
00314 }
00315
00316 sig.setPubKey(f, p, q, g);
00317 sig.update(H);
00318 result=sig.verify(sig_of_H);
00319 }
00320 else
00321 {
00322 Console.WriteLine("unknow alg");
00323 }
00324 state=STATE_END;
00325 break;
00326 }
00327 return result;
00328 }
00329
00330 public override String getKeyType()
00331 {
00332 if(type==DSS) return "DSA";
00333 return "RSA";
00334 }
00335
00336 public override int getState(){return state; }
00337 }
00338
00339 }
00340