1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46:
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54:
55:
60: public final class DiffieHellmanImpl
61: extends KeyAgreementSpi
62: {
63:
64: private DHPrivateKey key;
65:
66:
67: private byte[] result;
68:
69:
70: private boolean last_phase_done;
71:
72:
73: public DiffieHellmanImpl()
74: {
75: super();
76:
77: key = null;
78: result = null;
79: last_phase_done = false;
80: }
81:
82: protected Key engineDoPhase(Key incoming, boolean lastPhase)
83: throws InvalidKeyException
84: {
85: if (key == null)
86: throw new IllegalStateException("Not initialized");
87:
88: if (last_phase_done)
89: throw new IllegalStateException("Last phase already done");
90:
91: if (! (incoming instanceof DHPublicKey))
92: throw new InvalidKeyException("Key MUST be a DHPublicKey");
93:
94: DHPublicKey pub = (DHPublicKey) incoming;
95: DHParameterSpec s1 = key.getParams();
96: DHParameterSpec s2 = pub.getParams();
97: if (! s1.getG().equals(s2.getG()) || ! s1.getP().equals(s2.getP()))
98: throw new InvalidKeyException("Incompatible key");
99: if (! lastPhase)
100: throw new IllegalArgumentException(
101: "This key-agreement MUST be concluded in one step only");
102: BigInteger resultBI = pub.getY().modPow(key.getX(), s1.getP());
103: result = resultBI.toByteArray();
104: if (result[0] == 0x00)
105: {
106: byte[] buf = new byte[result.length - 1];
107: System.arraycopy(result, 1, buf, 0, buf.length);
108: result = buf;
109: }
110: last_phase_done = true;
111: return null;
112: }
113:
114: protected byte[] engineGenerateSecret()
115: {
116: checkState();
117: byte[] res = (byte[]) result.clone();
118: reset();
119: return res;
120: }
121:
122: protected int engineGenerateSecret(byte[] secret, int offset)
123: throws ShortBufferException
124: {
125: checkState();
126: if (result.length > secret.length - offset)
127: throw new ShortBufferException();
128: System.arraycopy(result, 0, secret, offset, result.length);
129: int res = result.length;
130: reset();
131: return res;
132: }
133:
134: protected SecretKey engineGenerateSecret(String algorithm)
135: throws InvalidKeyException
136: {
137: checkState();
138: byte[] s = (byte[]) result.clone();
139: SecretKey res = new SecretKeySpec(s, algorithm);
140: reset();
141: return res;
142: }
143:
144: protected void engineInit(Key key, SecureRandom random)
145: throws InvalidKeyException
146: {
147: if (! (key instanceof DHPrivateKey))
148: throw new InvalidKeyException("Key MUST be a DHPrivateKey");
149: this.key = (DHPrivateKey) key;
150: reset();
151: }
152:
153: protected void engineInit(Key key, AlgorithmParameterSpec params,
154: SecureRandom random)
155: throws InvalidKeyException
156: {
157: engineInit(key, random);
158: }
159:
160: private void reset()
161: {
162: result = null;
163: last_phase_done = false;
164: }
165:
166: private void checkState()
167: {
168: if (result == null || ! last_phase_done)
169: throw new IllegalStateException("Not finished");
170: }
171: }