3131import java .security .cert .X509Certificate ;
3232import java .text .MessageFormat ;
3333import java .util .ArrayList ;
34+ import java .util .Arrays ;
3435import java .util .Collection ;
3536import java .util .Collections ;
3637import java .util .HashSet ;
4445import sun .security .ssl .CipherSuite .KeyExchange ;
4546import sun .security .ssl .SSLHandshake .HandshakeMessage ;
4647import sun .security .ssl .X509Authentication .X509Possession ;
48+ import sun .security .ssl .X509Authentication .X509PossessionGenerator ;
4749
4850/**
4951 * Pack of the CertificateRequest handshake message.
@@ -716,12 +718,11 @@ public void consume(ConnectionContext context,
716718chc .handshakeSession .setPeerSupportedSignatureAlgorithms (sss );
717719chc .peerSupportedAuthorities =crm .getAuthorities ();
718720
719- // For TLS 1.2, we no longer use the certificate_types field
720- // from the CertificateRequest message to directly determine
721- // the SSLPossession. Instead, the choosePossession method
722- // will use the accepted signature schemes in the message to
723- // determine the set of acceptable certificate types to select from.
724- SSLPossession pos =choosePossession (chc );
721+ // For TLS 1.2, we need to use a combination of the CR message's
722+ // allowed key types and the signature algorithms in order to
723+ // find a certificate chain that has the right key and all certs
724+ // using one or more of the allowed cert signature schemes.
725+ SSLPossession pos =choosePossession (chc ,crm );
725726if (pos ==null ) {
726727return ;
727728 }
@@ -731,8 +732,8 @@ public void consume(ConnectionContext context,
731732SSLHandshake .CERTIFICATE_VERIFY );
732733 }
733734
734- private static SSLPossession choosePossession (HandshakeContext hc )
735- throws IOException {
735+ private static SSLPossession choosePossession (HandshakeContext hc ,
736+ T12CertificateRequestMessage crm ) throws IOException {
736737if (hc .peerRequestedCertSignSchemes ==null ||
737738hc .peerRequestedCertSignSchemes .isEmpty ()) {
738739if (SSLLogger .isOn &&SSLLogger .isOn ("ssl,handshake" )) {
@@ -742,6 +743,9 @@ private static SSLPossession choosePossession(HandshakeContext hc)
742743return null ;
743744 }
744745
746+ // Put the CR key type into a more friendly format for searching
747+ List <String >crKeyTypes =Arrays .asList (crm .getKeyTypes ());
748+
745749Collection <String >checkedKeyTypes =new HashSet <>();
746750for (SignatureScheme ss :hc .peerRequestedCertSignSchemes ) {
747751if (checkedKeyTypes .contains (ss .keyAlgorithm )) {
@@ -768,14 +772,35 @@ private static SSLPossession choosePossession(HandshakeContext hc)
768772continue ;
769773 }
770774
771- SSLAuthentication ka =X509Authentication .valueOf (ss );
775+ X509Authentication ka =X509Authentication .valueOf (ss );
772776if (ka ==null ) {
773777if (SSLLogger .isOn &&SSLLogger .isOn ("ssl,handshake" )) {
774778SSLLogger .warning (
775779"Unsupported authentication scheme: " +ss .name );
776780 }
777781checkedKeyTypes .add (ss .keyAlgorithm );
778782continue ;
783+ }else {
784+ // Any auth object will have a possession generator and
785+ // we need to make sure the key types for that generator
786+ // share at least one common algorithm with the CR's
787+ // allowed key types.
788+ if (ka .possessionGenerator instanceof
789+ X509PossessionGenerator ) {
790+ X509PossessionGenerator xpg =
791+ (X509PossessionGenerator )ka .possessionGenerator ;
792+ if (Collections .disjoint (crKeyTypes ,
793+ Arrays .asList (xpg .keyTypes ))) {
794+ if (SSLLogger .isOn &&
795+ SSLLogger .isOn ("ssl,handshake" )) {
796+ SSLLogger .warning (
797+ "Unsupported authentication scheme: " +
798+ ss .name );
799+ }
800+ checkedKeyTypes .add (ss .keyAlgorithm );
801+ continue ;
802+ }
803+ }
779804 }
780805
781806SSLPossession pos =ka .createPossession (hc );