• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
DhGroupExchange(BigInteger p, BigInteger g)39 	public DhGroupExchange(BigInteger p, BigInteger g)
40 	{
41 		this.p = p;
42 		this.g = g;
43 	}
44 
init(SecureRandom rnd)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 	 */
getE()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 	 */
getK()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 	 */
setF(BigInteger f)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 
calculateH(byte[] clientversion, byte[] serverversion, byte[] clientKexPayload, byte[] serverKexPayload, byte[] hostKey, DHGexParameters para)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