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.GordianStateAwareKeyPair;
22 import io.github.tonywasher.joceanus.gordianknot.api.keypair.spec.GordianKeyPairSpec;
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 myThat)) {
156 return false;
157 }
158
159
160 return getKeySpec().equals(myThat.getKeySpec())
161 && theKey.equals(myThat.getPublicKey());
162 }
163
164 @Override
165 public int hashCode() {
166 return Objects.hash(getKeySpec(), theKey);
167 }
168 }
169
170
171
172
173 public static class JcaPrivateKey
174 extends GordianPrivateKey {
175
176
177
178 private final PrivateKey theKey;
179
180
181
182
183
184
185
186 protected JcaPrivateKey(final GordianKeyPairSpec pKeySpec,
187 final PrivateKey pPrivateKey) {
188 super(pKeySpec);
189 theKey = pPrivateKey;
190 }
191
192
193
194
195
196
197 protected PrivateKey getPrivateKey() {
198 return theKey;
199 }
200
201 @Override
202 public boolean equals(final Object pThat) {
203
204 if (pThat == this) {
205 return true;
206 }
207 if (pThat == null) {
208 return false;
209 }
210
211
212 if (!(pThat instanceof JcaPrivateKey myThat)) {
213 return false;
214 }
215
216
217 return getKeySpec().equals(myThat.getKeySpec())
218 && theKey.equals(myThat.getPrivateKey());
219 }
220
221 @Override
222 public int hashCode() {
223 return Objects.hash(getKeySpec(), theKey);
224 }
225 }
226
227
228
229
230 public static class JcaStateAwarePrivateKey
231 extends JcaPrivateKey
232 implements GordianStateAwarePrivateKey {
233
234
235
236 private final PrivateKey thePrivateKey;
237
238
239
240
241
242
243
244 JcaStateAwarePrivateKey(final GordianKeyPairSpec pKeySpec,
245 final PrivateKey pKey) {
246 super(pKeySpec, pKey);
247 thePrivateKey = pKey;
248 }
249
250 @Override
251 public PrivateKey getPrivateKey() {
252 return thePrivateKey;
253 }
254
255 @Override
256 public long getUsagesRemaining() {
257 if (thePrivateKey instanceof LMSPrivateKey) {
258 return ((LMSPrivateKey) getPrivateKey()).getUsagesRemaining();
259 }
260 if (thePrivateKey instanceof XMSSMTPrivateKey) {
261 return ((XMSSMTPrivateKey) getPrivateKey()).getUsagesRemaining();
262 }
263 return thePrivateKey instanceof XMSSPrivateKey
264 ? ((XMSSPrivateKey) getPrivateKey()).getUsagesRemaining()
265 : 0;
266 }
267
268 @Override
269 public JcaStateAwarePrivateKey getKeyShard(final int pNumUsages) {
270 if (thePrivateKey instanceof LMSPrivateKey) {
271 return new JcaStateAwarePrivateKey(getKeySpec(), ((LMSPrivateKey) getPrivateKey()).extractKeyShard(pNumUsages));
272 }
273 if (thePrivateKey instanceof XMSSMTPrivateKey) {
274 return new JcaStateAwarePrivateKey(getKeySpec(), ((XMSSMTPrivateKey) getPrivateKey()).extractKeyShard(pNumUsages));
275 }
276 return thePrivateKey instanceof XMSSPrivateKey
277 ? new JcaStateAwarePrivateKey(getKeySpec(), ((XMSSPrivateKey) getPrivateKey()).extractKeyShard(pNumUsages))
278 : null;
279 }
280
281 @Override
282 public boolean equals(final Object pThat) {
283
284 if (pThat == this) {
285 return true;
286 }
287 if (pThat == null) {
288 return false;
289 }
290
291
292 if (!(pThat instanceof JcaStateAwarePrivateKey myThat)) {
293 return false;
294 }
295
296
297 return getKeySpec().equals(myThat.getKeySpec())
298 && thePrivateKey.equals(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 JcaDHPublicKey
311 extends JcaPublicKey {
312
313
314
315 private final BCDHPublicKey theKey;
316
317
318
319
320
321
322
323 protected JcaDHPublicKey(final GordianKeyPairSpec pKeySpec,
324 final BCDHPublicKey pPublicKey) {
325 super(pKeySpec, pPublicKey);
326 theKey = pPublicKey;
327 }
328
329 @Override
330 protected BCDHPublicKey getPublicKey() {
331 return theKey;
332 }
333
334 @Override
335 public boolean equals(final Object pThat) {
336
337 if (pThat == this) {
338 return true;
339 }
340 if (pThat == null) {
341 return false;
342 }
343
344
345 if (!(pThat instanceof JcaDHPublicKey myThat)) {
346 return false;
347 }
348
349
350 return getKeySpec().equals(myThat.getKeySpec())
351 && theKey.getY().equals(myThat.getPublicKey().getY())
352 && dhParamsAreEqual(theKey.getParams(), myThat.getPublicKey().getParams());
353 }
354
355 @Override
356 public int hashCode() {
357 return Objects.hash(getKeySpec(), theKey);
358 }
359 }
360
361
362
363
364
365
366
367
368 private static boolean dhParamsAreEqual(final DHParameterSpec pFirst,
369 final DHParameterSpec pSecond) {
370 final DHDomainParameterSpec myFirst = (DHDomainParameterSpec) pFirst;
371 final DHDomainParameterSpec mySecond = (DHDomainParameterSpec) pSecond;
372 return myFirst.getP().equals(mySecond.getP())
373 && myFirst.getG().equals(mySecond.getG())
374 && myFirst.getQ().equals(mySecond.getQ());
375 }
376
377
378
379
380 public static class JcaDHPrivateKey
381 extends JcaPrivateKey {
382
383
384
385 private final BCDHPrivateKey thePrivateKey;
386
387
388
389
390
391
392
393 JcaDHPrivateKey(final GordianKeyPairSpec pKeySpec,
394 final BCDHPrivateKey pKey) {
395 super(pKeySpec, pKey);
396 thePrivateKey = pKey;
397 }
398
399 @Override
400 public BCDHPrivateKey getPrivateKey() {
401 return thePrivateKey;
402 }
403
404 @Override
405 public boolean equals(final Object pThat) {
406
407 if (pThat == this) {
408 return true;
409 }
410 if (pThat == null) {
411 return false;
412 }
413
414
415 if (!(pThat instanceof JcaDHPrivateKey myThat)) {
416 return false;
417 }
418
419
420 return getKeySpec().equals(myThat.getKeySpec())
421 && thePrivateKey.getX().equals(myThat.getPrivateKey().getX())
422 && dhParamsAreEqual(thePrivateKey.getParams(), myThat.getPrivateKey().getParams());
423 }
424
425 @Override
426 public int hashCode() {
427 return Objects.hash(getKeySpec(), thePrivateKey);
428 }
429 }
430
431
432
433
434 public static class JcaStateAwareKeyPair
435 extends JcaKeyPair
436 implements GordianStateAwareKeyPair {
437
438
439
440
441
442
443 JcaStateAwareKeyPair(final JcaPublicKey pPublic,
444 final JcaStateAwarePrivateKey pPrivate) {
445 super(pPublic, pPrivate);
446 }
447
448 @Override
449 public JcaStateAwarePrivateKey getPrivateKey() {
450 return (JcaStateAwarePrivateKey) super.getPrivateKey();
451 }
452
453 @Override
454 public long getUsagesRemaining() {
455 return getPrivateKey().getUsagesRemaining();
456 }
457
458 @Override
459 public JcaStateAwareKeyPair getKeyPairShard(final int pNumUsages) {
460 return new JcaStateAwareKeyPair(getPublicKey(), getPrivateKey().getKeyShard(pNumUsages));
461 }
462 }
463 }