CertificateByteChooser { public CertificateKeyPair chooseCertificateKeyPair(Chooser chooser) { if (!chooser.getConfig().isAutoSelectCertificate()) { return chooser.getConfig().getDefaultExplicitCertificateKeyPair(); } NamedGroup namedGroup = chooser.getSelectedNamedGroup(); CertificateKeyType prefereredSignatureCertSignatureType = chooser.getConfig() .getPreferedCertificateSignatureType(); CertificateKeyType neededPublicKeyType; if (chooser.getSelectedProtocolVersion().isTLS13()) { neededPublicKeyType = prefereredSignatureCertSignatureType; } else { KeyExchangeAlgorithm keyExchangeAlgorithm = AlgorithmResolver.getKeyExchangeAlgorithm(chooser .getSelectedCipherSuite()); if (keyExchangeAlgorithm == null) { LOGGER.warn("CipherSuite does not specify a certificate kex. Using RSA."); keyExchangeAlgorithm = KeyExchangeAlgorithm.RSA; } switch (keyExchangeAlgorithm) { case DH_RSA: case DHE_RSA: case ECDH_RSA: case ECDHE_RSA: case RSA: case SRP_SHA_RSA: case PSK_RSA: if (prefereredSignatureCertSignatureType != CertificateKeyType.RSA) { LOGGER.warn("PreferedSignatureType does not match Ciphersuite - ignoring preference"); } prefereredSignatureCertSignatureType = CertificateKeyType.RSA; break; case ECDHE_ECDSA: case ECDH_ECDSA: case ECMQV_ECDSA: case CECPQ1_ECDSA: if (prefereredSignatureCertSignatureType != CertificateKeyType.ECDSA) { LOGGER.warn("PreferedSignatureType does not match Ciphersuite - ignoring preference"); } prefereredSignatureCertSignatureType = CertificateKeyType.ECDSA; break; case DHE_DSS: case DH_DSS: case SRP_SHA_DSS: if (prefereredSignatureCertSignatureType != CertificateKeyType.DSS) { LOGGER.warn("PreferedSignatureType does not match Ciphersuite - ignoring preference"); } prefereredSignatureCertSignatureType = CertificateKeyType.DSS; break; case VKO_GOST01: if (prefereredSignatureCertSignatureType != CertificateKeyType.GOST01) { LOGGER.warn("PreferedSignatureType does not match Ciphersuite - ignoring preference"); } prefereredSignatureCertSignatureType = CertificateKeyType.GOST01; break; case VKO_GOST12: if (prefereredSignatureCertSignatureType != CertificateKeyType.GOST01) { LOGGER.warn("PreferedSignatureType does not match Ciphersuite - ignoring preference"); } prefereredSignatureCertSignatureType = CertificateKeyType.GOST12; break; } neededPublicKeyType = keyExchangeAlgorithm.getRequiredCertPublicKeyType(); } CertificateKeyPair nextBestChoice = null; for (CertificateKeyPair pair : keyPairList) { if (pair.getCertPublicKeyType() == neededPublicKeyType && pair.getCertSignatureType() == prefereredSignatureCertSignatureType) { SignatureAndHashAlgorithm sigHashAlgo = SignatureAndHashAlgorithm.forCertificateKeyPair(pair, chooser); nextBestChoice = pair; if (neededPublicKeyType == CertificateKeyType.ECDSA) { if (pair.getSignatureGroup() == null) { if (namedGroup == pair.getSignatureGroup()) { return pair; } } if (namedGroup != pair.getPublicKeyGroup() || pair.getSignatureGroup() != pair.getSignatureGroup()) { continue; } } if (neededPublicKeyType == CertificateKeyType.RSA && sigHashAlgo.getSignatureAlgorithm().toString().startsWith("RSA_PSS") && sigHashAlgo.getHashAlgorithm() == HashAlgorithm.SHA512 && pair.getPublicKey().keysize() < 2048) { continue; } return pair; } } if (nextBestChoice != null) { LOGGER.warn("Could not find a fitting Certificate - ignoreing preferences..."); return nextBestChoice; } LOGGER.warn("Could not find a matching CertificateKeyPair - returning first in List"); if (keyPairList.isEmpty()) { throw new RuntimeException("Key Pair list is empty!"); } return keyPairList.get(0); } private  CertificateByteChooser(); static synchronized CertificateByteChooser getInstance(); List<CertificateKeyPair> getCertificateKeyPairList(); CertificateKeyPair chooseCertificateKeyPair(Chooser chooser);  }
@Test public void testChooseCertificateKeyPair() { }