28 import java.security.*; |
28 import java.security.*; |
29 import java.security.spec.AlgorithmParameterSpec; |
29 import java.security.spec.AlgorithmParameterSpec; |
30 import java.security.spec.ECParameterSpec; |
30 import java.security.spec.ECParameterSpec; |
31 import java.security.spec.MGF1ParameterSpec; |
31 import java.security.spec.MGF1ParameterSpec; |
32 import java.security.spec.PSSParameterSpec; |
32 import java.security.spec.PSSParameterSpec; |
|
33 import java.util.AbstractMap.SimpleImmutableEntry; |
33 import java.util.ArrayList; |
34 import java.util.ArrayList; |
34 import java.util.Arrays; |
35 import java.util.Arrays; |
35 import java.util.Collection; |
36 import java.util.Collection; |
36 import java.util.Collections; |
37 import java.util.Collections; |
37 import java.util.EnumSet; |
38 import java.util.EnumSet; |
38 import java.util.LinkedList; |
39 import java.util.LinkedList; |
39 import java.util.List; |
40 import java.util.List; |
|
41 import java.util.Map; |
40 import java.util.Set; |
42 import java.util.Set; |
41 import sun.security.ssl.NamedGroup.NamedGroupSpec; |
43 import sun.security.ssl.NamedGroup.NamedGroupSpec; |
42 import sun.security.ssl.SupportedGroupsExtension.SupportedGroups; |
44 import sun.security.ssl.SupportedGroupsExtension.SupportedGroups; |
43 import sun.security.ssl.X509Authentication.X509Possession; |
45 import sun.security.ssl.X509Authentication.X509Possession; |
44 import sun.security.util.KeyUtil; |
46 import sun.security.util.KeyUtil; |
423 } |
425 } |
424 |
426 |
425 return null; |
427 return null; |
426 } |
428 } |
427 |
429 |
428 static SignatureScheme getPreferableAlgorithm( |
430 static Map.Entry<SignatureScheme, Signature> getSignerOfPreferableAlgorithm( |
429 AlgorithmConstraints constraints, |
431 AlgorithmConstraints constraints, |
430 List<SignatureScheme> schemes, |
432 List<SignatureScheme> schemes, |
431 X509Possession x509Possession, |
433 X509Possession x509Possession, |
432 ProtocolVersion version) { |
434 ProtocolVersion version) { |
433 |
435 |
450 NamedGroupSpec.NAMED_GROUP_ECDHE)) { |
452 NamedGroupSpec.NAMED_GROUP_ECDHE)) { |
451 ECParameterSpec params = |
453 ECParameterSpec params = |
452 x509Possession.getECParameterSpec(); |
454 x509Possession.getECParameterSpec(); |
453 if (params != null && |
455 if (params != null && |
454 ss.namedGroup == NamedGroup.valueOf(params)) { |
456 ss.namedGroup == NamedGroup.valueOf(params)) { |
455 return ss; |
457 Signature signer = ss.getSigner(signingKey); |
|
458 if (signer != null) { |
|
459 return new SimpleImmutableEntry<>(ss, signer); |
|
460 } |
456 } |
461 } |
457 |
462 |
458 if (SSLLogger.isOn && |
463 if (SSLLogger.isOn && |
459 SSLLogger.isOn("ssl,handshake,verbose")) { |
464 SSLLogger.isOn("ssl,handshake,verbose")) { |
460 SSLLogger.finest( |
465 SSLLogger.finest( |
475 x509Possession.getECParameterSpec(); |
480 x509Possession.getECParameterSpec(); |
476 if (params != null) { |
481 if (params != null) { |
477 NamedGroup keyGroup = NamedGroup.valueOf(params); |
482 NamedGroup keyGroup = NamedGroup.valueOf(params); |
478 if (keyGroup != null && |
483 if (keyGroup != null && |
479 SupportedGroups.isSupported(keyGroup)) { |
484 SupportedGroups.isSupported(keyGroup)) { |
480 return ss; |
485 Signature signer = ss.getSigner(signingKey); |
|
486 if (signer != null) { |
|
487 return new SimpleImmutableEntry<>(ss, signer); |
|
488 } |
481 } |
489 } |
482 } |
490 } |
483 |
491 |
484 if (SSLLogger.isOn && |
492 if (SSLLogger.isOn && |
485 SSLLogger.isOn("ssl,handshake,verbose")) { |
493 SSLLogger.isOn("ssl,handshake,verbose")) { |
486 SSLLogger.finest( |
494 SSLLogger.finest( |
487 "Ignore the legacy signature algorithm (" + ss + |
495 "Ignore the legacy signature algorithm (" + ss + |
488 "), unsupported EC parameter spec: " + params); |
496 "), unsupported EC parameter spec: " + params); |
489 } |
497 } |
490 } else { |
498 } else { |
491 return ss; |
499 Signature signer = ss.getSigner(signingKey); |
|
500 if (signer != null) { |
|
501 return new SimpleImmutableEntry<>(ss, signer); |
|
502 } |
492 } |
503 } |
493 } |
504 } |
494 } |
505 } |
495 |
506 |
496 return null; |
507 return null; |
507 } |
518 } |
508 |
519 |
509 return new String[0]; |
520 return new String[0]; |
510 } |
521 } |
511 |
522 |
512 Signature getSignature(Key key) throws NoSuchAlgorithmException, |
523 // This method is used to get the signature instance of this signature |
|
524 // scheme for the specific public key. Unlike getSigner(), the exception |
|
525 // is bubbled up. If the public key does not support this signature |
|
526 // scheme, it normally means the TLS handshaking cannot continue and |
|
527 // the connection should be terminated. |
|
528 Signature getVerifier(PublicKey publicKey) throws NoSuchAlgorithmException, |
513 InvalidAlgorithmParameterException, InvalidKeyException { |
529 InvalidAlgorithmParameterException, InvalidKeyException { |
514 if (!isAvailable) { |
530 if (!isAvailable) { |
515 return null; |
531 return null; |
516 } |
532 } |
517 |
533 |
518 Signature signer = Signature.getInstance(algorithm); |
534 Signature verifier = Signature.getInstance(algorithm); |
519 if (key instanceof PublicKey) { |
535 SignatureUtil.initVerifyWithParam(verifier, publicKey, |
520 SignatureUtil.initVerifyWithParam(signer, (PublicKey)key, |
536 (signAlgParams != null ? signAlgParams.parameterSpec : null)); |
521 (signAlgParams != null ? |
537 |
522 signAlgParams.parameterSpec : null)); |
538 return verifier; |
523 } else { |
539 } |
524 SignatureUtil.initSignWithParam(signer, (PrivateKey)key, |
540 |
525 (signAlgParams != null ? |
541 // This method is also used to choose preferable signature scheme for the |
526 signAlgParams.parameterSpec : null), |
542 // specific private key. If the private key does not support the signature |
527 null); |
543 // scheme, {@code null} is returned, and the caller may fail back to next |
528 } |
544 // available signature scheme. |
529 |
545 private Signature getSigner(PrivateKey privateKey) { |
530 return signer; |
546 if (!isAvailable) { |
|
547 return null; |
|
548 } |
|
549 |
|
550 try { |
|
551 Signature signer = Signature.getInstance(algorithm); |
|
552 SignatureUtil.initSignWithParam(signer, privateKey, |
|
553 (signAlgParams != null ? signAlgParams.parameterSpec : null), |
|
554 null); |
|
555 return signer; |
|
556 } catch (NoSuchAlgorithmException | InvalidKeyException | |
|
557 InvalidAlgorithmParameterException nsae) { |
|
558 if (SSLLogger.isOn && |
|
559 SSLLogger.isOn("ssl,handshake,verbose")) { |
|
560 SSLLogger.finest( |
|
561 "Ignore unsupported signature algorithm (" + |
|
562 this.name + ")", nsae); |
|
563 } |
|
564 } |
|
565 |
|
566 return null; |
531 } |
567 } |
532 } |
568 } |