1 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ 2 /* 3 Copyright (c) 2002-2015 ymnk, JCraft,Inc. All rights reserved. 4 5 Redistribution and use in source and binary forms, with or without 6 modification, are permitted provided that the following conditions are met: 7 8 1. Redistributions of source code must retain the above copyright notice, 9 this list of conditions and the following disclaimer. 10 11 2. Redistributions in binary form must reproduce the above copyright 12 notice, this list of conditions and the following disclaimer in 13 the documentation and/or other materials provided with the distribution. 14 15 3. The names of the authors may not be used to endorse or promote products 16 derived from this software without specific prior written permission. 17 18 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 19 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, 21 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 22 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 package com.jcraft.jsch; 31 32 public class DHG1 extends KeyExchange{ 33 34 static final byte[] g={ 2 }; 35 static final byte[] p={ 36 (byte)0x00, 37 (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, 38 (byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34, 39 (byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1, 40 (byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74, 41 (byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22, 42 (byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD, 43 (byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B, 44 (byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37, 45 (byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45, 46 (byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6, 47 (byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B, 48 (byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED, 49 (byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5, 50 (byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6, 51 (byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE6,(byte)0x53,(byte)0x81, 52 (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF 53 }; 54 55 private static final int SSH_MSG_KEXDH_INIT= 30; 56 private static final int SSH_MSG_KEXDH_REPLY= 31; 57 58 private int state; 59 60 DH dh; 61 62 byte[] V_S; 63 byte[] V_C; 64 byte[] I_S; 65 byte[] I_C; 66 67 byte[] e; 68 69 private Buffer buf; 70 private Packet packet; 71 init(Session session, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C)72 public void init(Session session, 73 byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{ 74 this.session=session; 75 this.V_S=V_S; 76 this.V_C=V_C; 77 this.I_S=I_S; 78 this.I_C=I_C; 79 80 try{ 81 Class c=Class.forName(session.getConfig("sha-1")); 82 sha=(HASH)(c.newInstance()); 83 sha.init(); 84 } 85 catch(Exception e){ 86 System.err.println(e); 87 } 88 89 buf=new Buffer(); 90 packet=new Packet(buf); 91 92 try{ 93 Class c=Class.forName(session.getConfig("dh")); 94 dh=(DH)(c.newInstance()); 95 dh.init(); 96 } 97 catch(Exception e){ 98 //System.err.println(e); 99 throw e; 100 } 101 102 dh.setP(p); 103 dh.setG(g); 104 105 // The client responds with: 106 // byte SSH_MSG_KEXDH_INIT(30) 107 // mpint e <- g^x mod p 108 // x is a random number (1 < x < (p-1)/2) 109 110 e=dh.getE(); 111 112 packet.reset(); 113 buf.putByte((byte)SSH_MSG_KEXDH_INIT); 114 buf.putMPInt(e); 115 session.write(packet); 116 117 if(JSch.getLogger().isEnabled(Logger.INFO)){ 118 JSch.getLogger().log(Logger.INFO, 119 "SSH_MSG_KEXDH_INIT sent"); 120 JSch.getLogger().log(Logger.INFO, 121 "expecting SSH_MSG_KEXDH_REPLY"); 122 } 123 124 state=SSH_MSG_KEXDH_REPLY; 125 } 126 next(Buffer _buf)127 public boolean next(Buffer _buf) throws Exception{ 128 int i,j; 129 130 switch(state){ 131 case SSH_MSG_KEXDH_REPLY: 132 // The server responds with: 133 // byte SSH_MSG_KEXDH_REPLY(31) 134 // string server public host key and certificates (K_S) 135 // mpint f 136 // string signature of H 137 j=_buf.getInt(); 138 j=_buf.getByte(); 139 j=_buf.getByte(); 140 if(j!=31){ 141 System.err.println("type: must be 31 "+j); 142 return false; 143 } 144 145 K_S=_buf.getString(); 146 147 byte[] f=_buf.getMPInt(); 148 byte[] sig_of_H=_buf.getString(); 149 150 dh.setF(f); 151 152 dh.checkRange(); 153 154 K=normalize(dh.getK()); 155 156 //The hash H is computed as the HASH hash of the concatenation of the 157 //following: 158 // string V_C, the client's version string (CR and NL excluded) 159 // string V_S, the server's version string (CR and NL excluded) 160 // string I_C, the payload of the client's SSH_MSG_KEXINIT 161 // string I_S, the payload of the server's SSH_MSG_KEXINIT 162 // string K_S, the host key 163 // mpint e, exchange value sent by the client 164 // mpint f, exchange value sent by the server 165 // mpint K, the shared secret 166 // This value is called the exchange hash, and it is used to authenti- 167 // cate the key exchange. 168 buf.reset(); 169 buf.putString(V_C); buf.putString(V_S); 170 buf.putString(I_C); buf.putString(I_S); 171 buf.putString(K_S); 172 buf.putMPInt(e); buf.putMPInt(f); 173 buf.putMPInt(K); 174 byte[] foo=new byte[buf.getLength()]; 175 buf.getByte(foo); 176 sha.update(foo, 0, foo.length); 177 H=sha.digest(); 178 //System.err.print("H -> "); //dump(H, 0, H.length); 179 180 i=0; 181 j=0; 182 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| 183 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); 184 String alg=Util.byte2str(K_S, i, j); 185 i+=j; 186 187 boolean result = verify(alg, K_S, i, sig_of_H); 188 189 state=STATE_END; 190 return result; 191 } 192 return false; 193 } 194 getState()195 public int getState(){return state; } 196 } 197