1 /* 2 * Copyright (c) 2006-2011 Christian Plattner. All rights reserved. 3 * Please refer to the LICENSE.txt for licensing details. 4 */ 5 package ch.ethz.ssh2.crypto.dh; 6 7 import java.math.BigInteger; 8 import java.security.SecureRandom; 9 10 import ch.ethz.ssh2.DHGexParameters; 11 import ch.ethz.ssh2.crypto.digest.HashForSSH2Types; 12 13 /** 14 * DhGroupExchange. 15 * 16 * @author Christian Plattner 17 * @version 2.50, 03/15/10 18 */ 19 public class DhGroupExchange 20 { 21 /* Given by the standard */ 22 23 private BigInteger p; 24 private BigInteger g; 25 26 /* Client public and private */ 27 28 private BigInteger e; 29 private BigInteger x; 30 31 /* Server public */ 32 33 private BigInteger f; 34 35 /* Shared secret */ 36 37 private BigInteger k; 38 39 public DhGroupExchange(BigInteger p, BigInteger g) 40 { 41 this.p = p; 42 this.g = g; 43 } 44 45 public void init(SecureRandom rnd) 46 { 47 k = null; 48 49 x = new BigInteger(p.bitLength() - 1, rnd); 50 e = g.modPow(x, p); 51 } 52 53 /** 54 * @return Returns the e. 55 */ 56 public BigInteger getE() 57 { 58 if (e == null) 59 throw new IllegalStateException("Not initialized!"); 60 61 return e; 62 } 63 64 /** 65 * @return Returns the shared secret k. 66 */ 67 public BigInteger getK() 68 { 69 if (k == null) 70 throw new IllegalStateException("Shared secret not yet known, need f first!"); 71 72 return k; 73 } 74 75 /** 76 * Sets f and calculates the shared secret. 77 */ 78 public void setF(BigInteger f) 79 { 80 if (e == null) 81 throw new IllegalStateException("Not initialized!"); 82 83 BigInteger zero = BigInteger.valueOf(0); 84 85 if (zero.compareTo(f) >= 0 || p.compareTo(f) <= 0) 86 throw new IllegalArgumentException("Invalid f specified!"); 87 88 this.f = f; 89 this.k = f.modPow(x, p); 90 } 91 92 public byte[] calculateH(byte[] clientversion, byte[] serverversion, byte[] clientKexPayload, 93 byte[] serverKexPayload, byte[] hostKey, DHGexParameters para) 94 { 95 HashForSSH2Types hash = new HashForSSH2Types("SHA1"); 96 97 hash.updateByteString(clientversion); 98 hash.updateByteString(serverversion); 99 hash.updateByteString(clientKexPayload); 100 hash.updateByteString(serverKexPayload); 101 hash.updateByteString(hostKey); 102 if (para.getMin_group_len() > 0) 103 hash.updateUINT32(para.getMin_group_len()); 104 hash.updateUINT32(para.getPref_group_len()); 105 if (para.getMax_group_len() > 0) 106 hash.updateUINT32(para.getMax_group_len()); 107 hash.updateBigInt(p); 108 hash.updateBigInt(g); 109 hash.updateBigInt(e); 110 hash.updateBigInt(f); 111 hash.updateBigInt(k); 112 113 return hash.getDigest(); 114 } 115 } 116