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.spec.GordianKeyPairSpec;
22 import io.github.tonywasher.joceanus.gordianknot.api.sign.GordianNewSignParams;
23 import io.github.tonywasher.joceanus.gordianknot.api.sign.spec.GordianSignatureSpec;
24 import io.github.tonywasher.joceanus.gordianknot.impl.bc.BouncyKeyPair.BouncyPrivateKey;
25 import io.github.tonywasher.joceanus.gordianknot.impl.bc.BouncyKeyPair.BouncyPublicKey;
26 import io.github.tonywasher.joceanus.gordianknot.impl.bc.BouncySignature.BouncyDERCoder;
27 import io.github.tonywasher.joceanus.gordianknot.impl.bc.BouncySignature.BouncyDigestSignature;
28 import io.github.tonywasher.joceanus.gordianknot.impl.core.agree.GordianCoreAgreementFactory;
29 import io.github.tonywasher.joceanus.gordianknot.impl.core.base.GordianBaseFactory;
30 import io.github.tonywasher.joceanus.gordianknot.impl.core.encrypt.GordianCoreEncryptor;
31 import io.github.tonywasher.joceanus.gordianknot.impl.core.exc.GordianCryptoException;
32 import io.github.tonywasher.joceanus.gordianknot.impl.core.exc.GordianIOException;
33 import io.github.tonywasher.joceanus.gordianknot.impl.core.exc.GordianLogicException;
34 import io.github.tonywasher.joceanus.gordianknot.impl.core.keypair.GordianKeyPairValidity;
35 import io.github.tonywasher.joceanus.gordianknot.impl.core.spec.agree.GordianCoreAgreementSpec;
36 import io.github.tonywasher.joceanus.gordianknot.impl.core.spec.encrypt.GordianCoreEncryptorSpec;
37 import io.github.tonywasher.joceanus.gordianknot.impl.core.spec.keypair.GordianCoreElliptic;
38 import io.github.tonywasher.joceanus.gordianknot.impl.core.spec.keypair.GordianCoreKeyPairSpec;
39 import io.github.tonywasher.joceanus.gordianknot.impl.ext.engines.GordianEllipticEncryptor;
40 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
41 import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
42 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
43 import org.bouncycastle.asn1.x9.ECNamedCurveTable;
44 import org.bouncycastle.asn1.x9.X9ECParameters;
45 import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
46 import org.bouncycastle.crypto.DSA;
47 import org.bouncycastle.crypto.DerivationFunction;
48 import org.bouncycastle.crypto.InvalidCipherTextException;
49 import org.bouncycastle.crypto.SecretWithEncapsulation;
50 import org.bouncycastle.crypto.agreement.ECDHCBasicAgreement;
51 import org.bouncycastle.crypto.agreement.ECDHCUnifiedAgreement;
52 import org.bouncycastle.crypto.agreement.ECMQVBasicAgreement;
53 import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
54 import org.bouncycastle.crypto.kems.ECIESKEMExtractor;
55 import org.bouncycastle.crypto.kems.ECIESKEMGenerator;
56 import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
57 import org.bouncycastle.crypto.params.ECDHUPrivateParameters;
58 import org.bouncycastle.crypto.params.ECDHUPublicParameters;
59 import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
60 import org.bouncycastle.crypto.params.ECNamedDomainParameters;
61 import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
62 import org.bouncycastle.crypto.params.ECPublicKeyParameters;
63 import org.bouncycastle.crypto.params.MQVPrivateParameters;
64 import org.bouncycastle.crypto.params.MQVPublicParameters;
65 import org.bouncycastle.crypto.params.ParametersWithRandom;
66 import org.bouncycastle.crypto.util.PrivateKeyFactory;
67 import org.bouncycastle.crypto.util.PrivateKeyInfoFactory;
68 import org.bouncycastle.crypto.util.PublicKeyFactory;
69 import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory;
70 import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
71 import org.bouncycastle.util.BigIntegers;
72
73 import javax.security.auth.DestroyFailedException;
74 import java.io.IOException;
75 import java.math.BigInteger;
76 import java.security.spec.PKCS8EncodedKeySpec;
77 import java.security.spec.X509EncodedKeySpec;
78
79
80
81
82 public final class BouncyEllipticKeyPair {
83
84
85
86 private BouncyEllipticKeyPair() {
87 }
88
89
90
91
92 public static class BouncyECPublicKey
93 extends BouncyPublicKey<ECPublicKeyParameters> {
94
95
96
97
98
99
100 BouncyECPublicKey(final GordianKeyPairSpec pKeySpec,
101 final ECPublicKeyParameters pPublicKey) {
102 super(pKeySpec, pPublicKey);
103 }
104
105 @Override
106 protected boolean matchKey(final AsymmetricKeyParameter pThat) {
107
108 final ECPublicKeyParameters myThis = getPublicKey();
109 final ECPublicKeyParameters myThat = (ECPublicKeyParameters) pThat;
110
111
112 return compareKeys(myThis, myThat);
113 }
114
115
116
117
118
119
120
121 public boolean validPrivate(final BouncyECPrivateKey pPrivate) {
122 final ECPrivateKeyParameters myPrivate = pPrivate.getPrivateKey();
123 return getPublicKey().getParameters().equals(myPrivate.getParameters());
124 }
125
126
127
128
129
130
131
132
133 private static boolean compareKeys(final ECPublicKeyParameters pFirst,
134 final ECPublicKeyParameters pSecond) {
135 return pFirst.getQ().equals(pSecond.getQ())
136 && pFirst.getParameters().equals(pSecond.getParameters());
137 }
138 }
139
140
141
142
143 public static class BouncyECPrivateKey
144 extends BouncyPrivateKey<ECPrivateKeyParameters> {
145
146
147
148
149
150
151 BouncyECPrivateKey(final GordianKeyPairSpec pKeySpec,
152 final ECPrivateKeyParameters pPrivateKey) {
153 super(pKeySpec, pPrivateKey);
154 }
155
156 @Override
157 protected boolean matchKey(final AsymmetricKeyParameter pThat) {
158
159 final ECPrivateKeyParameters myThis = getPrivateKey();
160 final ECPrivateKeyParameters myThat = (ECPrivateKeyParameters) pThat;
161
162
163 return compareKeys(myThis, myThat);
164 }
165
166
167
168
169
170
171
172
173 private static boolean compareKeys(final ECPrivateKeyParameters pFirst,
174 final ECPrivateKeyParameters pSecond) {
175 return pFirst.getD().equals(pSecond.getD())
176 && pFirst.getParameters().equals(pSecond.getParameters());
177 }
178 }
179
180
181
182
183 public static class BouncyECKeyPairGenerator
184 extends BouncyKeyPairGenerator {
185
186
187
188 private final ECKeyPairGenerator theGenerator;
189
190
191
192
193
194
195
196
197 BouncyECKeyPairGenerator(final GordianBaseFactory pFactory,
198 final GordianKeyPairSpec pKeySpec) throws GordianException {
199
200 super(pFactory, pKeySpec);
201
202
203 theGenerator = newGenerator();
204
205
206 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
207 final GordianCoreElliptic myElliptic = myKeySpec.getElliptic();
208 final String myCurve = myElliptic.getCurveName();
209 final X9ECParameters x9 = myElliptic.hasCustomCurve()
210 ? ECUtil.getNamedCurveByName(myCurve)
211 : ECNamedCurveTable.getByName(myCurve);
212 if (x9 == null) {
213 throw new GordianLogicException("Invalid KeySpec - " + pKeySpec);
214 }
215
216
217 final ASN1ObjectIdentifier myOid = ECUtil.getNamedCurveOid(myCurve);
218 final ECNamedDomainParameters myDomain = new ECNamedDomainParameters(myOid, x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
219 final ECKeyGenerationParameters myParams = new ECKeyGenerationParameters(myDomain, getRandom());
220 theGenerator.init(myParams);
221 }
222
223
224
225
226
227
228 ECKeyPairGenerator newGenerator() {
229 return new ECKeyPairGenerator();
230 }
231
232 @Override
233 public BouncyKeyPair generateKeyPair() {
234
235 final AsymmetricCipherKeyPair myPair = theGenerator.generateKeyPair();
236 final BouncyECPublicKey myPublic = new BouncyECPublicKey(getKeySpec(), (ECPublicKeyParameters) myPair.getPublic());
237 final BouncyECPrivateKey myPrivate = new BouncyECPrivateKey(getKeySpec(), (ECPrivateKeyParameters) myPair.getPrivate());
238 return new BouncyKeyPair(myPublic, myPrivate);
239 }
240
241 @Override
242 public PKCS8EncodedKeySpec getPKCS8Encoding(final GordianKeyPair pKeyPair) throws GordianException {
243
244 try {
245
246 BouncyKeyPair.checkKeyPair(pKeyPair, getKeySpec());
247
248
249 final BouncyECPrivateKey myPrivateKey = (BouncyECPrivateKey) getPrivateKey(pKeyPair);
250 final ECPrivateKeyParameters myParms = myPrivateKey.getPrivateKey();
251 final PrivateKeyInfo myInfo = PrivateKeyInfoFactory.createPrivateKeyInfo(myParms);
252 return new PKCS8EncodedKeySpec(myInfo.getEncoded());
253
254 } catch (IOException e) {
255 throw new GordianCryptoException(ERROR_PARSE, e);
256 }
257 }
258
259 @Override
260 public BouncyKeyPair deriveKeyPair(final X509EncodedKeySpec pPublicKey,
261 final PKCS8EncodedKeySpec pPrivateKey) throws GordianException {
262
263 try {
264
265 checkKeySpec(pPrivateKey);
266
267
268 final BouncyECPublicKey myPublic = derivePublicKey(pPublicKey);
269 final PrivateKeyInfo myInfo = PrivateKeyInfo.getInstance(pPrivateKey.getEncoded());
270 final ECPrivateKeyParameters myParms = (ECPrivateKeyParameters) PrivateKeyFactory.createKey(myInfo);
271 final BouncyECPrivateKey myPrivate = new BouncyECPrivateKey(getKeySpec(), myParms);
272 final BouncyKeyPair myPair = new BouncyKeyPair(myPublic, myPrivate);
273
274
275 GordianKeyPairValidity.checkValidity(getFactory(), myPair);
276
277
278 return myPair;
279
280 } catch (IOException e) {
281 throw new GordianCryptoException(ERROR_PARSE, e);
282 }
283 }
284
285 @Override
286 public X509EncodedKeySpec getX509Encoding(final GordianKeyPair pKeyPair) throws GordianException {
287
288 try {
289
290 BouncyKeyPair.checkKeyPair(pKeyPair, getKeySpec());
291
292
293 final BouncyECPublicKey myPublicKey = (BouncyECPublicKey) getPublicKey(pKeyPair);
294 final ECPublicKeyParameters myParms = myPublicKey.getPublicKey();
295 final SubjectPublicKeyInfo myInfo = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(myParms);
296 return new X509EncodedKeySpec(myInfo.getEncoded());
297
298 } catch (IOException e) {
299 throw new GordianCryptoException(ERROR_PARSE, e);
300 }
301 }
302
303 @Override
304 public BouncyKeyPair derivePublicOnlyKeyPair(final X509EncodedKeySpec pEncodedKey) throws GordianException {
305 final BouncyECPublicKey myPublic = derivePublicKey(pEncodedKey);
306 return new BouncyKeyPair(myPublic);
307 }
308
309
310
311
312
313
314
315
316 private BouncyECPublicKey derivePublicKey(final X509EncodedKeySpec pEncodedKey) throws GordianException {
317
318 try {
319
320 checkKeySpec(pEncodedKey);
321
322
323 final SubjectPublicKeyInfo myInfo = SubjectPublicKeyInfo.getInstance(pEncodedKey.getEncoded());
324 final ECPublicKeyParameters myParms = (ECPublicKeyParameters) PublicKeyFactory.createKey(myInfo);
325 return new BouncyECPublicKey(getKeySpec(), myParms);
326
327 } catch (IOException e) {
328 throw new GordianCryptoException(ERROR_PARSE, e);
329 }
330 }
331 }
332
333
334
335
336 public static class BouncyECSignature
337 extends BouncyDigestSignature {
338
339
340
341 private final DSA theSigner;
342
343
344
345
346 private final BouncyDERCoder theCoder;
347
348
349
350
351
352
353
354
355 BouncyECSignature(final GordianBaseFactory pFactory,
356 final GordianSignatureSpec pSpec) throws GordianException {
357
358 super(pFactory, pSpec);
359
360
361 theSigner = BouncySignature.getDSASigner(pFactory, pSpec);
362 theCoder = new BouncyDERCoder();
363 }
364
365 @Override
366 public void initForSigning(final GordianNewSignParams pParams) throws GordianException {
367
368 super.initForSigning(pParams);
369 final BouncyKeyPair myPair = getKeyPair();
370 BouncyKeyPair.checkKeyPair(myPair);
371
372
373 final BouncyECPrivateKey myPrivate = (BouncyECPrivateKey) myPair.getPrivateKey();
374 final ParametersWithRandom myParms = new ParametersWithRandom(myPrivate.getPrivateKey(), getRandom());
375 theSigner.init(true, myParms);
376 }
377
378 @Override
379 public void initForVerify(final GordianNewSignParams pParams) throws GordianException {
380
381 super.initForVerify(pParams);
382 final BouncyKeyPair myPair = getKeyPair();
383 BouncyKeyPair.checkKeyPair(myPair);
384
385
386 final BouncyECPublicKey myPublic = (BouncyECPublicKey) myPair.getPublicKey();
387 theSigner.init(false, myPublic.getPublicKey());
388 }
389
390 @Override
391 public byte[] sign() throws GordianException {
392
393 checkMode(GordianSignatureMode.SIGN);
394
395
396 final BigInteger[] myValues = theSigner.generateSignature(getDigest());
397 return theCoder.dsaEncode(myValues[0], myValues[1]);
398 }
399
400 @Override
401 public boolean verify(final byte[] pSignature) throws GordianException {
402
403 checkMode(GordianSignatureMode.VERIFY);
404
405
406 final BigInteger[] myValues = theCoder.dsaDecode(pSignature);
407 return theSigner.verifySignature(getDigest(), myValues[0], myValues[1]);
408 }
409 }
410
411
412
413
414 public static class BouncyECIESAgreementEngine
415 extends BouncyAgreementBase {
416
417
418
419 private static final int KEYLEN = 32;
420
421
422
423
424 private final DerivationFunction theDerivation;
425
426
427
428
429
430
431
432
433 BouncyECIESAgreementEngine(final GordianCoreAgreementFactory pFactory,
434 final GordianCoreAgreementSpec pSpec) throws GordianException {
435
436 super(pFactory, pSpec);
437
438
439 theDerivation = newDerivationFunction();
440 }
441
442 @Override
443 public void buildClientHello() throws GordianException {
444
445 try {
446
447 final BouncyECPublicKey myPublic = (BouncyECPublicKey) getPublicKey(getServerKeyPair());
448 final ECIESKEMGenerator myGenerator = new ECIESKEMGenerator(KEYLEN, theDerivation, getRandom());
449 final SecretWithEncapsulation myResult = myGenerator.generateEncapsulated(myPublic.getPublicKey());
450
451
452 setEncapsulated(myResult.getEncapsulation());
453
454
455 storeSecret(myResult.getSecret());
456 myResult.destroy();
457
458 } catch (DestroyFailedException e) {
459 throw new GordianIOException("Failed to destroy secret", e);
460 }
461 }
462
463 @Override
464 public void processClientHello() throws GordianException {
465
466 final BouncyECPrivateKey myPrivate = (BouncyECPrivateKey) getPrivateKey(getServerKeyPair());
467 final ECIESKEMExtractor myExtractor = new ECIESKEMExtractor(myPrivate.getPrivateKey(), KEYLEN, theDerivation);
468
469
470 final byte[] myMessage = getEncapsulated();
471 storeSecret(myExtractor.extractSecret(myMessage));
472 }
473 }
474
475
476
477
478 public static class BouncyECAnonAgreementEngine
479 extends BouncyAgreementBase {
480
481
482
483 private final ECDHCBasicAgreement theAgreement;
484
485
486
487
488
489
490
491
492 BouncyECAnonAgreementEngine(final GordianCoreAgreementFactory pFactory,
493 final GordianCoreAgreementSpec pSpec) throws GordianException {
494
495 super(pFactory, pSpec);
496
497
498 theAgreement = new ECDHCBasicAgreement();
499 }
500
501 @Override
502 public void buildClientHello() throws GordianException {
503
504 final BouncyECPublicKey myPublic = (BouncyECPublicKey) getPublicKey(getServerKeyPair());
505 final BouncyECPrivateKey myPrivate = (BouncyECPrivateKey) getPrivateKey(getClientEphemeral());
506
507
508 theAgreement.init(myPrivate.getPrivateKey());
509 final BigInteger mySecretInt = theAgreement.calculateAgreement(myPublic.getPublicKey());
510 final byte[] mySecret = BigIntegers.asUnsignedByteArray(theAgreement.getFieldSize(), mySecretInt);
511
512
513 storeSecret(mySecret);
514 }
515
516 @Override
517 public void processClientHello() throws GordianException {
518
519 final BouncyECPublicKey myPublic = (BouncyECPublicKey) getPublicKey(getClientEphemeral());
520 final BouncyECPrivateKey myPrivate = (BouncyECPrivateKey) getPrivateKey(getServerKeyPair());
521
522
523 theAgreement.init(myPrivate.getPrivateKey());
524 final BigInteger mySecretInt = theAgreement.calculateAgreement(myPublic.getPublicKey());
525 final byte[] mySecret = BigIntegers.asUnsignedByteArray(theAgreement.getFieldSize(), mySecretInt);
526
527
528 storeSecret(mySecret);
529 }
530 }
531
532
533
534
535 public static class BouncyECBasicAgreementEngine
536 extends BouncyAgreementBase {
537
538
539
540 private final ECDHCBasicAgreement theAgreement;
541
542
543
544
545
546
547
548
549 BouncyECBasicAgreementEngine(final GordianCoreAgreementFactory pFactory,
550 final GordianCoreAgreementSpec pSpec) throws GordianException {
551
552 super(pFactory, pSpec);
553
554
555 theAgreement = new ECDHCBasicAgreement();
556 }
557
558 @Override
559 public void processClientHello() throws GordianException {
560
561 final BouncyECPublicKey myPublic = (BouncyECPublicKey) getPublicKey(getClientKeyPair());
562 final BouncyECPrivateKey myPrivate = (BouncyECPrivateKey) getPrivateKey(getServerKeyPair());
563
564
565 theAgreement.init(myPrivate.getPrivateKey());
566 final BigInteger mySecretInt = theAgreement.calculateAgreement(myPublic.getPublicKey());
567 final byte[] mySecret = BigIntegers.asUnsignedByteArray(theAgreement.getFieldSize(), mySecretInt);
568
569
570 storeSecret(mySecret);
571 }
572
573 @Override
574 public void processServerHello() throws GordianException {
575
576 final BouncyECPublicKey myPublic = (BouncyECPublicKey) getPublicKey(getServerKeyPair());
577 final BouncyECPrivateKey myPrivate = (BouncyECPrivateKey) getPrivateKey(getClientKeyPair());
578
579
580 theAgreement.init(myPrivate.getPrivateKey());
581 final BigInteger mySecretInt = theAgreement.calculateAgreement(myPublic.getPublicKey());
582 final byte[] mySecret = BigIntegers.asUnsignedByteArray(theAgreement.getFieldSize(), mySecretInt);
583
584
585 storeSecret(mySecret);
586 }
587 }
588
589
590
591
592 public static class BouncyECUnifiedAgreementEngine
593 extends BouncyAgreementBase {
594
595
596
597 private final ECDHCUnifiedAgreement theAgreement;
598
599
600
601
602
603
604
605
606 BouncyECUnifiedAgreementEngine(final GordianCoreAgreementFactory pFactory,
607 final GordianCoreAgreementSpec pSpec) throws GordianException {
608
609 super(pFactory, pSpec);
610
611
612 theAgreement = new ECDHCUnifiedAgreement();
613 }
614
615 @Override
616 public void processClientHello() throws GordianException {
617
618 final BouncyECPublicKey myClientPublic = (BouncyECPublicKey) getPublicKey(getClientKeyPair());
619 final BouncyECPublicKey myClientEphPublic = (BouncyECPublicKey) getPublicKey(getClientEphemeral());
620 final BouncyECPrivateKey myPrivate = (BouncyECPrivateKey) getPrivateKey(getServerKeyPair());
621 final BouncyECPublicKey myEphPublic = (BouncyECPublicKey) getPublicKey(getServerEphemeral());
622 final BouncyECPrivateKey myEphPrivate = (BouncyECPrivateKey) getPrivateKey(getServerEphemeral());
623
624
625 final ECDHUPrivateParameters myPrivParams
626 = new ECDHUPrivateParameters(myPrivate.getPrivateKey(), myEphPrivate.getPrivateKey(), myEphPublic.getPublicKey());
627 theAgreement.init(myPrivParams);
628 final ECDHUPublicParameters myPubParams
629 = new ECDHUPublicParameters(myClientPublic.getPublicKey(), myClientEphPublic.getPublicKey());
630 storeSecret(theAgreement.calculateAgreement(myPubParams));
631 }
632
633 @Override
634 public void processServerHello() throws GordianException {
635
636 final BouncyECPublicKey myServerPublic = (BouncyECPublicKey) getPublicKey(getServerKeyPair());
637 final BouncyECPublicKey myServerEphPublic = (BouncyECPublicKey) getPublicKey(getServerEphemeral());
638 final BouncyECPrivateKey myPrivate = (BouncyECPrivateKey) getPrivateKey(getClientKeyPair());
639 final BouncyECPublicKey myEphPublic = (BouncyECPublicKey) getPublicKey(getClientEphemeral());
640 final BouncyECPrivateKey myEphPrivate = (BouncyECPrivateKey) getPrivateKey(getClientEphemeral());
641
642
643 final ECDHUPrivateParameters myPrivParams
644 = new ECDHUPrivateParameters(myPrivate.getPrivateKey(), myEphPrivate.getPrivateKey(), myEphPublic.getPublicKey());
645 theAgreement.init(myPrivParams);
646 final ECDHUPublicParameters myPubParams
647 = new ECDHUPublicParameters(myServerPublic.getPublicKey(), myServerEphPublic.getPublicKey());
648 storeSecret(theAgreement.calculateAgreement(myPubParams));
649 }
650 }
651
652
653
654
655 public static class BouncyECMQVAgreementEngine
656 extends BouncyAgreementBase {
657
658
659
660 private final ECMQVBasicAgreement theAgreement;
661
662
663
664
665
666
667
668
669 BouncyECMQVAgreementEngine(final GordianCoreAgreementFactory pFactory,
670 final GordianCoreAgreementSpec pSpec) throws GordianException {
671
672 super(pFactory, pSpec);
673
674
675 theAgreement = new ECMQVBasicAgreement();
676 }
677
678 @Override
679 public void processClientHello() throws GordianException {
680
681 final BouncyECPublicKey myClientPublic = (BouncyECPublicKey) getPublicKey(getClientKeyPair());
682 final BouncyECPublicKey myClientEphPublic = (BouncyECPublicKey) getPublicKey(getClientEphemeral());
683 final BouncyECPrivateKey myPrivate = (BouncyECPrivateKey) getPrivateKey(getServerKeyPair());
684 final BouncyECPublicKey myEphPublic = (BouncyECPublicKey) getPublicKey(getServerEphemeral());
685 final BouncyECPrivateKey myEphPrivate = (BouncyECPrivateKey) getPrivateKey(getServerEphemeral());
686
687
688 final MQVPrivateParameters myPrivParams
689 = new MQVPrivateParameters(myPrivate.getPrivateKey(), myEphPrivate.getPrivateKey(), myEphPublic.getPublicKey());
690 theAgreement.init(myPrivParams);
691 final MQVPublicParameters myPubParams
692 = new MQVPublicParameters(myClientPublic.getPublicKey(), myClientEphPublic.getPublicKey());
693 storeSecret(BigIntegers.asUnsignedByteArray(theAgreement.getFieldSize(), theAgreement.calculateAgreement(myPubParams)));
694 }
695
696 @Override
697 public void processServerHello() throws GordianException {
698
699 final BouncyECPublicKey myServerPublic = (BouncyECPublicKey) getPublicKey(getServerKeyPair());
700 final BouncyECPublicKey myServerEphPublic = (BouncyECPublicKey) getPublicKey(getServerEphemeral());
701 final BouncyECPrivateKey myPrivate = (BouncyECPrivateKey) getPrivateKey(getClientKeyPair());
702 final BouncyECPublicKey myEphPublic = (BouncyECPublicKey) getPublicKey(getClientEphemeral());
703 final BouncyECPrivateKey myEphPrivate = (BouncyECPrivateKey) getPrivateKey(getClientEphemeral());
704
705
706 final MQVPrivateParameters myPrivParams
707 = new MQVPrivateParameters(myPrivate.getPrivateKey(), myEphPrivate.getPrivateKey(), myEphPublic.getPublicKey());
708 theAgreement.init(myPrivParams);
709 final MQVPublicParameters myPubParams
710 = new MQVPublicParameters(myServerPublic.getPublicKey(), myServerEphPublic.getPublicKey());
711 storeSecret(BigIntegers.asUnsignedByteArray(theAgreement.getFieldSize(), theAgreement.calculateAgreement(myPubParams)));
712 }
713 }
714
715
716
717
718 public static class BouncyECEncryptor
719 extends GordianCoreEncryptor {
720
721
722
723 private final GordianEllipticEncryptor theEncryptor;
724
725
726
727
728
729
730
731 BouncyECEncryptor(final GordianBaseFactory pFactory,
732 final GordianCoreEncryptorSpec pSpec) {
733
734 super(pFactory, pSpec);
735 theEncryptor = new GordianEllipticEncryptor();
736 }
737
738 @Override
739 protected BouncyPublicKey<?> getPublicKey() {
740 return (BouncyPublicKey<?>) super.getPublicKey();
741 }
742
743 @Override
744 protected BouncyPrivateKey<?> getPrivateKey() {
745 return (BouncyPrivateKey<?>) super.getPrivateKey();
746 }
747
748 @Override
749 public void initForEncrypt(final GordianKeyPair pKeyPair) throws GordianException {
750
751 BouncyKeyPair.checkKeyPair(pKeyPair);
752 super.initForEncrypt(pKeyPair);
753
754
755 final ECPublicKeyParameters myParms = (ECPublicKeyParameters) getPublicKey().getPublicKey();
756 theEncryptor.initForEncrypt(myParms, getRandom());
757 }
758
759 @Override
760 public void initForDecrypt(final GordianKeyPair pKeyPair) throws GordianException {
761
762 BouncyKeyPair.checkKeyPair(pKeyPair);
763 super.initForDecrypt(pKeyPair);
764
765
766 final ECPrivateKeyParameters myParms = (ECPrivateKeyParameters) getPrivateKey().getPrivateKey();
767 theEncryptor.initForDecrypt(myParms);
768 }
769
770 @Override
771 public byte[] encrypt(final byte[] pBytes) throws GordianException {
772 try {
773
774 checkMode(GordianEncryptMode.ENCRYPT);
775
776
777 return theEncryptor.encrypt(pBytes);
778 } catch (InvalidCipherTextException e) {
779 throw new GordianCryptoException("Failed to process data", e);
780 }
781 }
782
783 @Override
784 public byte[] decrypt(final byte[] pBytes) throws GordianException {
785 try {
786
787 checkMode(GordianEncryptMode.DECRYPT);
788
789
790 return theEncryptor.decrypt(pBytes);
791 } catch (InvalidCipherTextException e) {
792 throw new GordianCryptoException("Failed to process data", e);
793 }
794 }
795 }
796 }