Mercurial > 510Connectbot
comparison src/ch/ethz/ssh2/crypto/dh/DhExchange.java @ 342:175c7d68f3c4
merge ganymed into mainline
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Thu, 31 Jul 2014 16:33:38 -0700 |
parents | 1d400fd78e4a |
children |
comparison
equal
deleted
inserted
replaced
272:ce2f4e397703 | 342:175c7d68f3c4 |
---|---|
1 /** | |
2 * | |
3 */ | |
4 package ch.ethz.ssh2.crypto.dh; | |
5 | |
6 import java.io.IOException; | |
7 import java.math.BigInteger; | |
8 import java.security.InvalidAlgorithmParameterException; | |
9 import java.security.InvalidKeyException; | |
10 import java.security.KeyFactory; | |
11 import java.security.KeyPair; | |
12 import java.security.KeyPairGenerator; | |
13 import java.security.NoSuchAlgorithmException; | |
14 import java.security.spec.InvalidKeySpecException; | |
15 | |
16 import javax.crypto.KeyAgreement; | |
17 import javax.crypto.interfaces.DHPrivateKey; | |
18 import javax.crypto.interfaces.DHPublicKey; | |
19 import javax.crypto.spec.DHParameterSpec; | |
20 import javax.crypto.spec.DHPublicKeySpec; | |
21 | |
22 /** | |
23 * @author kenny | |
24 * | |
25 */ | |
26 public class DhExchange extends GenericDhExchange { | |
27 | |
28 /* Given by the standard */ | |
29 | |
30 private static final BigInteger P1 = new BigInteger( | |
31 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" | |
32 + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" | |
33 + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" | |
34 + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" | |
35 + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" | |
36 + "FFFFFFFFFFFFFFFF", 16); | |
37 | |
38 private static final BigInteger P14 = new BigInteger( | |
39 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" | |
40 + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" | |
41 + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" | |
42 + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" | |
43 + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" | |
44 + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" | |
45 + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" | |
46 + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" | |
47 + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" | |
48 + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" | |
49 + "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 16); | |
50 | |
51 private static final BigInteger G = BigInteger.valueOf(2); | |
52 | |
53 /* Client public and private */ | |
54 | |
55 private DHPrivateKey clientPrivate; | |
56 private DHPublicKey clientPublic; | |
57 | |
58 /* Server public */ | |
59 | |
60 private DHPublicKey serverPublic; | |
61 private byte[] f; | |
62 | |
63 @Override | |
64 public void init(String name) throws IOException { | |
65 final DHParameterSpec spec; | |
66 | |
67 if ("diffie-hellman-group1-sha1".equals(name)) { | |
68 spec = new DHParameterSpec(P1, G); | |
69 } | |
70 else if ("diffie-hellman-group14-sha1".equals(name)) { | |
71 spec = new DHParameterSpec(P14, G); | |
72 } | |
73 else { | |
74 throw new IllegalArgumentException("Unknown DH group " + name); | |
75 } | |
76 | |
77 try { | |
78 KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH"); | |
79 kpg.initialize(spec); | |
80 KeyPair pair = kpg.generateKeyPair(); | |
81 clientPrivate = (DHPrivateKey) pair.getPrivate(); | |
82 clientPublic = (DHPublicKey) pair.getPublic(); | |
83 } | |
84 catch (NoSuchAlgorithmException e) { | |
85 throw(IOException) new IOException("No DH keypair generator").initCause(e); | |
86 } | |
87 catch (InvalidAlgorithmParameterException e) { | |
88 throw(IOException) new IOException("Invalid DH parameters").initCause(e); | |
89 } | |
90 } | |
91 | |
92 @Override | |
93 public byte[] getE() { | |
94 if (clientPublic == null) | |
95 throw new IllegalStateException("DhExchange not initialized!"); | |
96 | |
97 return clientPublic.getY().toByteArray(); | |
98 } | |
99 | |
100 @Override | |
101 protected byte[] getServerE() { | |
102 if (serverPublic == null) | |
103 throw new IllegalStateException("DhExchange not initialized!"); | |
104 | |
105 return serverPublic.getY().toByteArray(); | |
106 } | |
107 | |
108 @Override | |
109 public byte[] getF() { | |
110 return f; | |
111 } | |
112 | |
113 @Override | |
114 public void setF(byte[] f) throws IOException { | |
115 if (clientPublic == null) | |
116 throw new IllegalStateException("DhExchange not initialized!"); | |
117 | |
118 final KeyAgreement ka; | |
119 | |
120 try { | |
121 KeyFactory kf = KeyFactory.getInstance("DH"); | |
122 DHParameterSpec params = clientPublic.getParams(); | |
123 this.f = f; | |
124 this.serverPublic = (DHPublicKey) kf.generatePublic(new DHPublicKeySpec( | |
125 new BigInteger(f), params.getP(), params.getG())); | |
126 ka = KeyAgreement.getInstance("DH"); | |
127 ka.init(clientPrivate); | |
128 ka.doPhase(serverPublic, true); | |
129 } | |
130 catch (NoSuchAlgorithmException e) { | |
131 throw(IOException) new IOException("No DH key agreement method").initCause(e); | |
132 } | |
133 catch (InvalidKeyException e) { | |
134 throw(IOException) new IOException("Invalid DH key").initCause(e); | |
135 } | |
136 catch (InvalidKeySpecException e) { | |
137 throw(IOException) new IOException("Invalid DH key").initCause(e); | |
138 } | |
139 | |
140 sharedSecret = new BigInteger(ka.generateSecret()); | |
141 } | |
142 | |
143 @Override | |
144 public String getHashAlgo() { | |
145 return "SHA1"; | |
146 } | |
147 } |