302 if (x509Possession == null || ecdheCredentials == null) { |
302 if (x509Possession == null || ecdheCredentials == null) { |
303 shc.conContext.fatal(Alert.HANDSHAKE_FAILURE, |
303 shc.conContext.fatal(Alert.HANDSHAKE_FAILURE, |
304 "No sufficient ECDHE key agreement parameters negotiated"); |
304 "No sufficient ECDHE key agreement parameters negotiated"); |
305 } |
305 } |
306 |
306 |
307 return new ECDHEKAKeyDerivation(shc, |
307 return new KAKeyDerivation("ECDH", shc, |
308 x509Possession.popPrivateKey, ecdheCredentials.popPublicKey); |
308 x509Possession.popPrivateKey, ecdheCredentials.popPublicKey); |
309 } |
309 } |
310 |
310 |
311 private SSLKeyDerivation createClientKeyDerivation( |
311 private SSLKeyDerivation createClientKeyDerivation( |
312 ClientHandshakeContext chc) throws IOException { |
312 ClientHandshakeContext chc) throws IOException { |
395 if (ecdhePossession == null || ecdheCredentials == null) { |
395 if (ecdhePossession == null || ecdheCredentials == null) { |
396 context.conContext.fatal(Alert.HANDSHAKE_FAILURE, |
396 context.conContext.fatal(Alert.HANDSHAKE_FAILURE, |
397 "No sufficient ECDHE key agreement parameters negotiated"); |
397 "No sufficient ECDHE key agreement parameters negotiated"); |
398 } |
398 } |
399 |
399 |
400 return new ECDHEKAKeyDerivation(context, |
400 return new KAKeyDerivation("ECDH", context, |
401 ecdhePossession.privateKey, ecdheCredentials.popPublicKey); |
401 ecdhePossession.privateKey, ecdheCredentials.popPublicKey); |
402 } |
|
403 } |
|
404 |
|
405 private static final |
|
406 class ECDHEKAKeyDerivation implements SSLKeyDerivation { |
|
407 private final HandshakeContext context; |
|
408 private final PrivateKey localPrivateKey; |
|
409 private final PublicKey peerPublicKey; |
|
410 |
|
411 ECDHEKAKeyDerivation(HandshakeContext context, |
|
412 PrivateKey localPrivateKey, |
|
413 PublicKey peerPublicKey) { |
|
414 this.context = context; |
|
415 this.localPrivateKey = localPrivateKey; |
|
416 this.peerPublicKey = peerPublicKey; |
|
417 } |
|
418 |
|
419 @Override |
|
420 public SecretKey deriveKey(String algorithm, |
|
421 AlgorithmParameterSpec params) throws IOException { |
|
422 if (!context.negotiatedProtocol.useTLS13PlusSpec()) { |
|
423 return t12DeriveKey(algorithm, params); |
|
424 } else { |
|
425 return t13DeriveKey(algorithm, params); |
|
426 } |
|
427 } |
|
428 |
|
429 private SecretKey t12DeriveKey(String algorithm, |
|
430 AlgorithmParameterSpec params) throws IOException { |
|
431 try { |
|
432 KeyAgreement ka = JsseJce.getKeyAgreement("ECDH"); |
|
433 ka.init(localPrivateKey); |
|
434 ka.doPhase(peerPublicKey, true); |
|
435 SecretKey preMasterSecret = |
|
436 ka.generateSecret("TlsPremasterSecret"); |
|
437 |
|
438 SSLMasterKeyDerivation mskd = |
|
439 SSLMasterKeyDerivation.valueOf( |
|
440 context.negotiatedProtocol); |
|
441 if (mskd == null) { |
|
442 // unlikely |
|
443 throw new SSLHandshakeException( |
|
444 "No expected master key derivation for protocol: " + |
|
445 context.negotiatedProtocol.name); |
|
446 } |
|
447 SSLKeyDerivation kd = mskd.createKeyDerivation( |
|
448 context, preMasterSecret); |
|
449 return kd.deriveKey("MasterSecret", params); |
|
450 } catch (GeneralSecurityException gse) { |
|
451 throw (SSLHandshakeException) new SSLHandshakeException( |
|
452 "Could not generate secret").initCause(gse); |
|
453 } |
|
454 } |
|
455 |
|
456 private SecretKey t13DeriveKey(String algorithm, |
|
457 AlgorithmParameterSpec params) throws IOException { |
|
458 try { |
|
459 KeyAgreement ka = JsseJce.getKeyAgreement("ECDH"); |
|
460 ka.init(localPrivateKey); |
|
461 ka.doPhase(peerPublicKey, true); |
|
462 SecretKey sharedSecret = |
|
463 ka.generateSecret("TlsPremasterSecret"); |
|
464 |
|
465 HashAlg hashAlg = context.negotiatedCipherSuite.hashAlg; |
|
466 SSLKeyDerivation kd = context.handshakeKeyDerivation; |
|
467 HKDF hkdf = new HKDF(hashAlg.name); |
|
468 if (kd == null) { // No PSK is in use. |
|
469 // If PSK is not in use Early Secret will still be |
|
470 // HKDF-Extract(0, 0). |
|
471 byte[] zeros = new byte[hashAlg.hashLength]; |
|
472 SecretKeySpec ikm = |
|
473 new SecretKeySpec(zeros, "TlsPreSharedSecret"); |
|
474 SecretKey earlySecret = |
|
475 hkdf.extract(zeros, ikm, "TlsEarlySecret"); |
|
476 kd = new SSLSecretDerivation(context, earlySecret); |
|
477 } |
|
478 |
|
479 // derive salt secret |
|
480 SecretKey saltSecret = kd.deriveKey("TlsSaltSecret", null); |
|
481 |
|
482 // derive handshake secret |
|
483 return hkdf.extract(saltSecret, sharedSecret, algorithm); |
|
484 } catch (GeneralSecurityException gse) { |
|
485 throw (SSLHandshakeException) new SSLHandshakeException( |
|
486 "Could not generate secret").initCause(gse); |
|
487 } |
|
488 } |
402 } |
489 } |
403 } |
490 } |
404 } |