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: || s1.getL() != s2.getL())
99: throw new InvalidKeyException("Incompatible key");
100: if (! lastPhase)
101: throw new IllegalArgumentException(
102: "This key-agreement MUST be concluded in one step only");
103: BigInteger resultBI = pub.getY().modPow(key.getX(), s1.getP());
104: result = resultBI.toByteArray();
105: if (result[0] == 0x00)
106: {
107: byte[] buf = new byte[result.length - 1];
108: System.arraycopy(result, 1, buf, 0, buf.length);
109: result = buf;
110: }
111: last_phase_done = true;
112: return null;
113: }
114:
115: protected byte[] engineGenerateSecret()
116: {
117: checkState();
118: byte[] res = (byte[]) result.clone();
119: reset();
120: return res;
121: }
122:
123: protected int engineGenerateSecret(byte[] secret, int offset)
124: throws ShortBufferException
125: {
126: checkState();
127: if (result.length > secret.length - offset)
128: throw new ShortBufferException();
129: System.arraycopy(result, 0, secret, offset, result.length);
130: int res = result.length;
131: reset();
132: return res;
133: }
134:
135: protected SecretKey engineGenerateSecret(String algorithm)
136: throws InvalidKeyException
137: {
138: checkState();
139: byte[] s = (byte[]) result.clone();
140: SecretKey res = new SecretKeySpec(s, algorithm);
141: reset();
142: return res;
143: }
144:
145: protected void engineInit(Key key, SecureRandom random)
146: throws InvalidKeyException
147: {
148: if (! (key instanceof DHPrivateKey))
149: throw new InvalidKeyException("Key MUST be a DHPrivateKey");
150: this.key = (DHPrivateKey) key;
151: reset();
152: }
153:
154: protected void engineInit(Key key, AlgorithmParameterSpec params,
155: SecureRandom random)
156: throws InvalidKeyException
157: {
158: engineInit(key, random);
159: }
160:
161: private void reset()
162: {
163: result = null;
164: last_phase_done = false;
165: }
166:
167: private void checkState()
168: {
169: if (result == null || ! last_phase_done)
170: throw new IllegalStateException("Not finished");
171: }
172: }