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