1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.gordianknot.impl.bc;
18
19 import io.github.tonywasher.joceanus.gordianknot.api.base.GordianException;
20 import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianKeyPair;
21 import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianKeyPairSpec;
22 import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianStateAwareKeyPair;
23 import io.github.tonywasher.joceanus.gordianknot.impl.core.exc.GordianDataException;
24 import io.github.tonywasher.joceanus.gordianknot.impl.core.keypair.GordianCoreKeyPair;
25 import io.github.tonywasher.joceanus.gordianknot.impl.core.keypair.GordianPrivateKey;
26 import io.github.tonywasher.joceanus.gordianknot.impl.core.keypair.GordianPrivateKey.GordianStateAwarePrivateKey;
27 import io.github.tonywasher.joceanus.gordianknot.impl.core.keypair.GordianPublicKey;
28 import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
29
30 import java.util.Objects;
31
32
33
34
35 public class BouncyKeyPair
36 extends GordianCoreKeyPair {
37
38
39
40
41
42 protected BouncyKeyPair(final BouncyPublicKey<?> pPublic) {
43 this(pPublic, null);
44 }
45
46
47
48
49
50
51
52 protected BouncyKeyPair(final BouncyPublicKey<?> pPublic,
53 final BouncyPrivateKey<?> pPrivate) {
54 super(pPublic, pPrivate);
55 }
56
57 @Override
58 public BouncyPublicKey<?> getPublicKey() {
59 return (BouncyPublicKey<?>) super.getPublicKey();
60 }
61
62 @Override
63 public BouncyPrivateKey<?> getPrivateKey() {
64 return (BouncyPrivateKey<?>) super.getPrivateKey();
65 }
66
67 @Override
68 public BouncyKeyPair getPublicOnly() {
69 return new BouncyKeyPair(getPublicKey());
70 }
71
72
73
74
75
76
77
78 public static void checkKeyPair(final GordianKeyPair pKeyPair) throws GordianException {
79
80 if (!(pKeyPair instanceof BouncyKeyPair)) {
81
82 throw new GordianDataException("Invalid KeyPair");
83 }
84 }
85
86
87
88
89
90
91
92
93 public static void checkKeyPair(final GordianKeyPair pKeyPair,
94 final GordianKeyPairSpec pSpec) throws GordianException {
95
96 checkKeyPair(pKeyPair);
97
98
99 if (!pSpec.equals(pKeyPair.getKeyPairSpec())) {
100
101 throw new GordianDataException("Invalid KeyPairType");
102 }
103 }
104
105
106
107
108
109
110 public abstract static class BouncyPublicKey<T extends AsymmetricKeyParameter>
111 extends GordianPublicKey {
112
113
114
115 private final T theKey;
116
117
118
119
120
121
122
123 protected BouncyPublicKey(final GordianKeyPairSpec pKeySpec,
124 final T pKey) {
125 super(pKeySpec);
126 theKey = pKey;
127 }
128
129
130
131
132
133
134 public T getPublicKey() {
135 return theKey;
136 }
137
138
139
140
141
142
143
144 protected abstract boolean matchKey(AsymmetricKeyParameter pThat);
145
146 @Override
147 public boolean equals(final Object pThat) {
148
149 if (pThat == this) {
150 return true;
151 }
152 if (pThat == null) {
153 return false;
154 }
155
156
157 if (!(pThat instanceof BouncyPublicKey)) {
158 return false;
159 }
160
161
162 final BouncyPublicKey<?> myThat = (BouncyPublicKey<?>) pThat;
163
164
165 return getKeySpec().equals(myThat.getKeySpec())
166 && matchKey(myThat.getPublicKey());
167 }
168
169 @Override
170 public int hashCode() {
171 return Objects.hash(getKeySpec().hashCode(), theKey);
172 }
173 }
174
175
176
177
178
179
180 public abstract static class BouncyPrivateKey<T extends AsymmetricKeyParameter>
181 extends GordianPrivateKey {
182
183
184
185 private final T theKey;
186
187
188
189
190
191
192
193 protected BouncyPrivateKey(final GordianKeyPairSpec pKeySpec,
194 final T pKey) {
195 super(pKeySpec);
196 theKey = pKey;
197 }
198
199
200
201
202
203
204 public T getPrivateKey() {
205 return theKey;
206 }
207
208
209
210
211
212
213
214 protected abstract boolean matchKey(AsymmetricKeyParameter pThat);
215
216 @Override
217 public boolean equals(final Object pThat) {
218
219 if (pThat == this) {
220 return true;
221 }
222 if (pThat == null) {
223 return false;
224 }
225
226
227 if (!(pThat instanceof BouncyPrivateKey)) {
228 return false;
229 }
230
231
232 final BouncyPrivateKey<?> myThat = (BouncyPrivateKey<?>) pThat;
233
234
235 return getKeySpec().equals(myThat.getKeySpec())
236 && matchKey(myThat.getPrivateKey());
237 }
238
239 @Override
240 public int hashCode() {
241 return Objects.hash(getKeySpec(), theKey);
242 }
243 }
244
245
246
247
248
249
250 public abstract static class BouncyStateAwarePrivateKey<T extends AsymmetricKeyParameter>
251 extends BouncyPrivateKey<T>
252 implements GordianStateAwarePrivateKey {
253
254
255
256 private final T thePrivateKey;
257
258
259
260
261
262
263
264 protected BouncyStateAwarePrivateKey(final GordianKeyPairSpec pKeySpec,
265 final T pKey) {
266 super(pKeySpec, pKey);
267 thePrivateKey = pKey;
268 }
269
270 @Override
271 public T getPrivateKey() {
272 return thePrivateKey;
273 }
274
275 @Override
276 public abstract BouncyStateAwarePrivateKey<T> getKeyShard(int pNumUsages);
277
278 @Override
279 public boolean equals(final Object pThat) {
280
281 if (pThat == this) {
282 return true;
283 }
284 if (pThat == null) {
285 return false;
286 }
287
288
289 if (!(pThat instanceof BouncyStateAwarePrivateKey)) {
290 return false;
291 }
292
293
294 final BouncyStateAwarePrivateKey<?> myThat = (BouncyStateAwarePrivateKey<?>) pThat;
295
296
297 return getKeySpec().equals(myThat.getKeySpec())
298 && matchKey(myThat.getPrivateKey());
299 }
300
301 @Override
302 public int hashCode() {
303 return Objects.hash(getKeySpec(), thePrivateKey);
304 }
305 }
306
307
308
309
310 public static class BouncyStateAwareKeyPair
311 extends BouncyKeyPair
312 implements GordianStateAwareKeyPair {
313
314
315
316
317
318
319 BouncyStateAwareKeyPair(final BouncyPublicKey<?> pPublic,
320 final BouncyStateAwarePrivateKey<?> pPrivate) {
321 super(pPublic, pPrivate);
322 }
323
324 @Override
325 public BouncyStateAwarePrivateKey<?> getPrivateKey() {
326 return (BouncyStateAwarePrivateKey<?>) super.getPrivateKey();
327 }
328
329 @Override
330 public long getUsagesRemaining() {
331 return getPrivateKey().getUsagesRemaining();
332 }
333
334 @Override
335 public BouncyStateAwareKeyPair getKeyPairShard(final int pNumUsages) {
336 return new BouncyStateAwareKeyPair(getPublicKey(), getPrivateKey().getKeyShard(pNumUsages));
337 }
338 }
339 }