00001
00002
00003
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 package com.jcraft.jsch;
00031
00044 public class DHG14 extends KeyExchange{
00045
00046 static final byte[] g={ 2 };
00047 static final byte[] p={
00048 (byte)0x00,
00049 (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
00050 (byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
00051 (byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
00052 (byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
00053 (byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
00054 (byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
00055 (byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
00056 (byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
00057 (byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
00058 (byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
00059 (byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
00060 (byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
00061 (byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
00062 (byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
00063 (byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D,
00064 (byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05,
00065 (byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A,
00066 (byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F,
00067 (byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96,
00068 (byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB,
00069 (byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D,
00070 (byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04,
00071 (byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C,
00072 (byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B,
00073 (byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03,
00074 (byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F,
00075 (byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9,
00076 (byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18,
00077 (byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5,
00078 (byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10,
00079 (byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAC,(byte)0xAA,(byte)0x68,
00080 (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
00081 };
00082
00083 private static final int SSH_MSG_KEXDH_INIT= 30;
00084 private static final int SSH_MSG_KEXDH_REPLY= 31;
00085
00086 static final int RSA=0;
00087 static final int DSS=1;
00088 private int type=0;
00089
00090 private int state;
00091
00092 DH dh;
00093
00094 byte[] V_S;
00095 byte[] V_C;
00096 byte[] I_S;
00097 byte[] I_C;
00098
00099 byte[] e;
00100
00101 private Buffer buf;
00102 private Packet packet;
00103
00104 public void init(Session session,
00105 byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
00106 this.session=session;
00107 this.V_S=V_S;
00108 this.V_C=V_C;
00109 this.I_S=I_S;
00110 this.I_C=I_C;
00111
00112 try{
00113 Class c=Class.forName(session.getConfig("sha-1"));
00114 sha=(HASH)(c.newInstance());
00115 sha.init();
00116 }
00117 catch(Exception e){
00118 System.err.println(e);
00119 }
00120
00121 buf=new Buffer();
00122 packet=new Packet(buf);
00123
00124 try{
00125 Class c=Class.forName(session.getConfig("dh"));
00126 dh=(DH)(c.newInstance());
00127 dh.init();
00128 }
00129 catch(Exception e){
00130
00131 throw e;
00132 }
00133
00134 dh.setP(p);
00135 dh.setG(g);
00136
00137
00138
00139
00140
00141 e=dh.getE();
00142 packet.reset();
00143 buf.putByte((byte)SSH_MSG_KEXDH_INIT);
00144 buf.putMPInt(e);
00145
00146 if(V_S==null){
00147 return;
00148 }
00149
00150 session.write(packet);
00151
00152 if(JSch.getLogger().isEnabled(Logger.INFO)){
00153 JSch.getLogger().log(Logger.INFO,
00154 "SSH_MSG_KEXDH_INIT sent");
00155 JSch.getLogger().log(Logger.INFO,
00156 "expecting SSH_MSG_KEXDH_REPLY");
00157 }
00158
00159 state=SSH_MSG_KEXDH_REPLY;
00160 }
00161
00162 public boolean next(Buffer _buf) throws Exception{
00163 int i,j;
00164
00165 switch(state){
00166 case SSH_MSG_KEXDH_REPLY:
00167
00168
00169
00170
00171
00172 j=_buf.getInt();
00173 j=_buf.getByte();
00174 j=_buf.getByte();
00175 if(j!=31){
00176 System.err.println("type: must be 31 "+j);
00177 return false;
00178 }
00179
00180 K_S=_buf.getString();
00181
00182
00183
00184
00185
00186
00187
00188 byte[] f=_buf.getMPInt();
00189 byte[] sig_of_H=_buf.getString();
00190
00191 dh.setF(f);
00192 K=dh.getK();
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 buf.reset();
00207 buf.putString(V_C); buf.putString(V_S);
00208 buf.putString(I_C); buf.putString(I_S);
00209 buf.putString(K_S);
00210 buf.putMPInt(e); buf.putMPInt(f);
00211 buf.putMPInt(K);
00212 byte[] foo=new byte[buf.getLength()];
00213 buf.getByte(foo);
00214 sha.update(foo, 0, foo.length);
00215 H=sha.digest();
00216
00217
00218 i=0;
00219 j=0;
00220 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00221 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00222 String alg=Util.byte2str(K_S, i, j);
00223 i+=j;
00224
00225 boolean result=false;
00226
00227 if(alg.equals("ssh-rsa")){
00228 byte[] tmp;
00229 byte[] ee;
00230 byte[] n;
00231
00232 type=RSA;
00233
00234 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00235 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00236 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00237 ee=tmp;
00238 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00239 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00240 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00241 n=tmp;
00242
00243 SignatureRSA sig=null;
00244 try{
00245 Class c=Class.forName(session.getConfig("signature.rsa"));
00246 sig=(SignatureRSA)(c.newInstance());
00247 sig.init();
00248 }
00249 catch(Exception e){
00250 System.err.println(e);
00251 }
00252
00253 sig.setPubKey(ee, n);
00254 sig.update(H);
00255 result=sig.verify(sig_of_H);
00256
00257 if(JSch.getLogger().isEnabled(Logger.INFO)){
00258 JSch.getLogger().log(Logger.INFO,
00259 "ssh_rsa_verify: signature "+result);
00260 }
00261
00262 }
00263 else if(alg.equals("ssh-dss")){
00264 byte[] q=null;
00265 byte[] tmp;
00266 byte[] p;
00267 byte[] g;
00268
00269 type=DSS;
00270
00271 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00272 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00273 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00274 p=tmp;
00275 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00276 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00277 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00278 q=tmp;
00279 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00280 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00281 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00282 g=tmp;
00283 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00284 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00285 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00286 f=tmp;
00287
00288 SignatureDSA sig=null;
00289 try{
00290 Class c=Class.forName(session.getConfig("signature.dss"));
00291 sig=(SignatureDSA)(c.newInstance());
00292 sig.init();
00293 }
00294 catch(Exception e){
00295 System.err.println(e);
00296 }
00297 sig.setPubKey(f, p, q, g);
00298 sig.update(H);
00299 result=sig.verify(sig_of_H);
00300
00301 if(JSch.getLogger().isEnabled(Logger.INFO)){
00302 JSch.getLogger().log(Logger.INFO,
00303 "ssh_dss_verify: signature "+result);
00304 }
00305
00306 }
00307 else{
00308 System.err.println("unknown alg");
00309 }
00310 state=STATE_END;
00311 return result;
00312 }
00313 return false;
00314 }
00315
00316 public String getKeyType(){
00317 if(type==DSS) return "DSA";
00318 return "RSA";
00319 }
00320
00321 public int getState(){return state; }
00322 }