1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.gordianknot.impl.jca;
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.jcajce.provider.asymmetric.dh.BCDHPrivateKey;
29 import org.bouncycastle.jcajce.provider.asymmetric.dh.BCDHPublicKey;
30 import org.bouncycastle.jcajce.spec.DHDomainParameterSpec;
31 import org.bouncycastle.pqc.jcajce.interfaces.LMSPrivateKey;
32 import org.bouncycastle.pqc.jcajce.interfaces.XMSSMTPrivateKey;
33 import org.bouncycastle.pqc.jcajce.interfaces.XMSSPrivateKey;
34
35 import javax.crypto.spec.DHParameterSpec;
36 import java.security.PrivateKey;
37 import java.security.PublicKey;
38 import java.util.Objects;
39
40
41
42
43 public class JcaKeyPair
44 extends GordianCoreKeyPair {
45
46
47
48
49
50 protected JcaKeyPair(final JcaPublicKey pPublic) {
51 this(pPublic, null);
52 }
53
54
55
56
57
58
59
60 protected JcaKeyPair(final JcaPublicKey pPublic,
61 final JcaPrivateKey pPrivate) {
62 super(pPublic, pPrivate);
63 }
64
65 @Override
66 public JcaPublicKey getPublicKey() {
67 return (JcaPublicKey) super.getPublicKey();
68 }
69
70 @Override
71 public JcaPrivateKey getPrivateKey() {
72 return (JcaPrivateKey) super.getPrivateKey();
73 }
74
75 @Override
76 public JcaKeyPair getPublicOnly() {
77 return new JcaKeyPair(getPublicKey());
78 }
79
80
81
82
83
84
85
86 public static void checkKeyPair(final GordianKeyPair pKeyPair) throws GordianException {
87
88 if (!(pKeyPair instanceof JcaKeyPair)) {
89
90 throw new GordianDataException("Invalid KeyPair");
91 }
92 }
93
94
95
96
97
98
99
100
101 public static void checkKeyPair(final GordianKeyPair pKeyPair,
102 final GordianKeyPairSpec pSpec) throws GordianException {
103
104 checkKeyPair(pKeyPair);
105
106
107 if (!pSpec.equals(pKeyPair.getKeyPairSpec())) {
108
109 throw new GordianDataException("Invalid KeyPairType");
110 }
111 }
112
113
114
115
116 public static class JcaPublicKey
117 extends GordianPublicKey {
118
119
120
121 private final PublicKey theKey;
122
123
124
125
126
127
128
129 protected JcaPublicKey(final GordianKeyPairSpec pKeySpec,
130 final PublicKey pPublicKey) {
131 super(pKeySpec);
132 theKey = pPublicKey;
133 }
134
135
136
137
138
139
140 protected PublicKey getPublicKey() {
141 return theKey;
142 }
143
144 @Override
145 public boolean equals(final Object pThat) {
146
147 if (pThat == this) {
148 return true;
149 }
150 if (pThat == null) {
151 return false;
152 }
153
154
155 if (!(pThat instanceof JcaPublicKey)) {
156 return false;
157 }
158
159
160 final JcaPublicKey myThat = (JcaPublicKey) pThat;
161
162
163 return getKeySpec().equals(myThat.getKeySpec())
164 && theKey.equals(myThat.getPublicKey());
165 }
166
167 @Override
168 public int hashCode() {
169 return Objects.hash(getKeySpec(), theKey);
170 }
171 }
172
173
174
175
176 public static class JcaPrivateKey
177 extends GordianPrivateKey {
178
179
180
181 private final PrivateKey theKey;
182
183
184
185
186
187
188
189 protected JcaPrivateKey(final GordianKeyPairSpec pKeySpec,
190 final PrivateKey pPrivateKey) {
191 super(pKeySpec);
192 theKey = pPrivateKey;
193 }
194
195
196
197
198
199
200 protected PrivateKey getPrivateKey() {
201 return theKey;
202 }
203
204 @Override
205 public boolean equals(final Object pThat) {
206
207 if (pThat == this) {
208 return true;
209 }
210 if (pThat == null) {
211 return false;
212 }
213
214
215 if (!(pThat instanceof JcaPrivateKey)) {
216 return false;
217 }
218
219
220 final JcaPrivateKey myThat = (JcaPrivateKey) pThat;
221
222
223 return getKeySpec().equals(myThat.getKeySpec())
224 && theKey.equals(myThat.getPrivateKey());
225 }
226
227 @Override
228 public int hashCode() {
229 return Objects.hash(getKeySpec(), theKey);
230 }
231 }
232
233
234
235
236 public static class JcaStateAwarePrivateKey
237 extends JcaPrivateKey
238 implements GordianStateAwarePrivateKey {
239
240
241
242 private final PrivateKey thePrivateKey;
243
244
245
246
247
248
249
250 JcaStateAwarePrivateKey(final GordianKeyPairSpec pKeySpec,
251 final PrivateKey pKey) {
252 super(pKeySpec, pKey);
253 thePrivateKey = pKey;
254 }
255
256 @Override
257 public PrivateKey getPrivateKey() {
258 return thePrivateKey;
259 }
260
261 @Override
262 public long getUsagesRemaining() {
263 if (thePrivateKey instanceof LMSPrivateKey) {
264 return ((LMSPrivateKey) getPrivateKey()).getUsagesRemaining();
265 }
266 if (thePrivateKey instanceof XMSSMTPrivateKey) {
267 return ((XMSSMTPrivateKey) getPrivateKey()).getUsagesRemaining();
268 }
269 return thePrivateKey instanceof XMSSPrivateKey
270 ? ((XMSSPrivateKey) getPrivateKey()).getUsagesRemaining()
271 : 0;
272 }
273
274 @Override
275 public JcaStateAwarePrivateKey getKeyShard(final int pNumUsages) {
276 if (thePrivateKey instanceof LMSPrivateKey) {
277 return new JcaStateAwarePrivateKey(getKeySpec(), ((LMSPrivateKey) getPrivateKey()).extractKeyShard(pNumUsages));
278 }
279 if (thePrivateKey instanceof XMSSMTPrivateKey) {
280 return new JcaStateAwarePrivateKey(getKeySpec(), ((XMSSMTPrivateKey) getPrivateKey()).extractKeyShard(pNumUsages));
281 }
282 return thePrivateKey instanceof XMSSPrivateKey
283 ? new JcaStateAwarePrivateKey(getKeySpec(), ((XMSSPrivateKey) getPrivateKey()).extractKeyShard(pNumUsages))
284 : null;
285 }
286
287 @Override
288 public boolean equals(final Object pThat) {
289
290 if (pThat == this) {
291 return true;
292 }
293 if (pThat == null) {
294 return false;
295 }
296
297
298 if (!(pThat instanceof JcaStateAwarePrivateKey)) {
299 return false;
300 }
301
302
303 final JcaStateAwarePrivateKey myThat = (JcaStateAwarePrivateKey) pThat;
304
305
306 return getKeySpec().equals(myThat.getKeySpec())
307 && thePrivateKey.equals(myThat.getPrivateKey());
308 }
309
310 @Override
311 public int hashCode() {
312 return Objects.hash(getKeySpec(), thePrivateKey);
313 }
314 }
315
316
317
318
319 public static class JcaDHPublicKey
320 extends JcaPublicKey {
321
322
323
324 private final BCDHPublicKey theKey;
325
326
327
328
329
330
331
332 protected JcaDHPublicKey(final GordianKeyPairSpec pKeySpec,
333 final BCDHPublicKey pPublicKey) {
334 super(pKeySpec, pPublicKey);
335 theKey = pPublicKey;
336 }
337
338 @Override
339 protected BCDHPublicKey getPublicKey() {
340 return theKey;
341 }
342
343 @Override
344 public boolean equals(final Object pThat) {
345
346 if (pThat == this) {
347 return true;
348 }
349 if (pThat == null) {
350 return false;
351 }
352
353
354 if (!(pThat instanceof JcaDHPublicKey)) {
355 return false;
356 }
357
358
359 final JcaDHPublicKey myThat = (JcaDHPublicKey) pThat;
360
361
362 return getKeySpec().equals(myThat.getKeySpec())
363 && theKey.getY().equals(myThat.getPublicKey().getY())
364 && dhParamsAreEqual(theKey.getParams(), myThat.getPublicKey().getParams());
365 }
366
367 @Override
368 public int hashCode() {
369 return Objects.hash(getKeySpec(), theKey);
370 }
371 }
372
373
374
375
376
377
378
379
380 private static boolean dhParamsAreEqual(final DHParameterSpec pFirst,
381 final DHParameterSpec pSecond) {
382 final DHDomainParameterSpec myFirst = (DHDomainParameterSpec) pFirst;
383 final DHDomainParameterSpec mySecond = (DHDomainParameterSpec) pSecond;
384 return myFirst.getP().equals(mySecond.getP())
385 && myFirst.getG().equals(mySecond.getG())
386 && myFirst.getQ().equals(mySecond.getQ());
387 }
388
389
390
391
392 public static class JcaDHPrivateKey
393 extends JcaPrivateKey {
394
395
396
397 private final BCDHPrivateKey thePrivateKey;
398
399
400
401
402
403
404
405 JcaDHPrivateKey(final GordianKeyPairSpec pKeySpec,
406 final BCDHPrivateKey pKey) {
407 super(pKeySpec, pKey);
408 thePrivateKey = pKey;
409 }
410
411 @Override
412 public BCDHPrivateKey getPrivateKey() {
413 return thePrivateKey;
414 }
415
416 @Override
417 public boolean equals(final Object pThat) {
418
419 if (pThat == this) {
420 return true;
421 }
422 if (pThat == null) {
423 return false;
424 }
425
426
427 if (!(pThat instanceof JcaDHPrivateKey)) {
428 return false;
429 }
430
431
432 final JcaDHPrivateKey myThat = (JcaDHPrivateKey) pThat;
433
434
435 return getKeySpec().equals(myThat.getKeySpec())
436 && thePrivateKey.getX().equals(myThat.getPrivateKey().getX())
437 && dhParamsAreEqual(thePrivateKey.getParams(), myThat.getPrivateKey().getParams());
438 }
439
440 @Override
441 public int hashCode() {
442 return Objects.hash(getKeySpec(), thePrivateKey);
443 }
444 }
445
446
447
448
449 public static class JcaStateAwareKeyPair
450 extends JcaKeyPair
451 implements GordianStateAwareKeyPair {
452
453
454
455
456
457
458 JcaStateAwareKeyPair(final JcaPublicKey pPublic,
459 final JcaStateAwarePrivateKey pPrivate) {
460 super(pPublic, pPrivate);
461 }
462
463 @Override
464 public JcaStateAwarePrivateKey getPrivateKey() {
465 return (JcaStateAwarePrivateKey) super.getPrivateKey();
466 }
467
468 @Override
469 public long getUsagesRemaining() {
470 return getPrivateKey().getUsagesRemaining();
471 }
472
473 @Override
474 public JcaStateAwareKeyPair getKeyPairShard(final int pNumUsages) {
475 return new JcaStateAwareKeyPair(getPublicKey(), getPrivateKey().getKeyShard(pNumUsages));
476 }
477 }
478 }