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.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.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<?> myThat)) {
158 return false;
159 }
160
161
162 return getKeySpec().equals(myThat.getKeySpec())
163 && matchKey(myThat.getPublicKey());
164 }
165
166 @Override
167 public int hashCode() {
168 return Objects.hash(getKeySpec().hashCode(), theKey);
169 }
170 }
171
172
173
174
175
176
177 public abstract static class BouncyPrivateKey<T extends AsymmetricKeyParameter>
178 extends GordianPrivateKey {
179
180
181
182 private final T theKey;
183
184
185
186
187
188
189
190 protected BouncyPrivateKey(final GordianKeyPairSpec pKeySpec,
191 final T pKey) {
192 super(pKeySpec);
193 theKey = pKey;
194 }
195
196
197
198
199
200
201 public T getPrivateKey() {
202 return theKey;
203 }
204
205
206
207
208
209
210
211 protected abstract boolean matchKey(AsymmetricKeyParameter pThat);
212
213 @Override
214 public boolean equals(final Object pThat) {
215
216 if (pThat == this) {
217 return true;
218 }
219 if (pThat == null) {
220 return false;
221 }
222
223
224 if (!(pThat instanceof BouncyPrivateKey<?> myThat)) {
225 return false;
226 }
227
228
229 return getKeySpec().equals(myThat.getKeySpec())
230 && matchKey(myThat.getPrivateKey());
231 }
232
233 @Override
234 public int hashCode() {
235 return Objects.hash(getKeySpec(), theKey);
236 }
237 }
238
239
240
241
242
243
244 public abstract static class BouncyStateAwarePrivateKey<T extends AsymmetricKeyParameter>
245 extends BouncyPrivateKey<T>
246 implements GordianStateAwarePrivateKey {
247
248
249
250 private final T thePrivateKey;
251
252
253
254
255
256
257
258 protected BouncyStateAwarePrivateKey(final GordianKeyPairSpec pKeySpec,
259 final T pKey) {
260 super(pKeySpec, pKey);
261 thePrivateKey = pKey;
262 }
263
264 @Override
265 public T getPrivateKey() {
266 return thePrivateKey;
267 }
268
269 @Override
270 public abstract BouncyStateAwarePrivateKey<T> getKeyShard(int pNumUsages);
271
272 @Override
273 public boolean equals(final Object pThat) {
274
275 if (pThat == this) {
276 return true;
277 }
278 if (pThat == null) {
279 return false;
280 }
281
282
283 if (!(pThat instanceof BouncyStateAwarePrivateKey<?> myThat)) {
284 return false;
285 }
286
287
288 return getKeySpec().equals(myThat.getKeySpec())
289 && matchKey(myThat.getPrivateKey());
290 }
291
292 @Override
293 public int hashCode() {
294 return Objects.hash(getKeySpec(), thePrivateKey);
295 }
296 }
297
298
299
300
301 public static class BouncyStateAwareKeyPair
302 extends BouncyKeyPair
303 implements GordianStateAwareKeyPair {
304
305
306
307
308
309
310 BouncyStateAwareKeyPair(final BouncyPublicKey<?> pPublic,
311 final BouncyStateAwarePrivateKey<?> pPrivate) {
312 super(pPublic, pPrivate);
313 }
314
315 @Override
316 public BouncyStateAwarePrivateKey<?> getPrivateKey() {
317 return (BouncyStateAwarePrivateKey<?>) super.getPrivateKey();
318 }
319
320 @Override
321 public long getUsagesRemaining() {
322 return getPrivateKey().getUsagesRemaining();
323 }
324
325 @Override
326 public BouncyStateAwareKeyPair getKeyPairShard(final int pNumUsages) {
327 return new BouncyStateAwareKeyPair(getPublicKey(), getPrivateKey().getKeyShard(pNumUsages));
328 }
329 }
330 }