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