SSLHandshakeException - java.security.cert.CertPathValidatorException: требуется ненулевое дерево политик, а дерево политик равно null

У меня есть корневой сертификат сервера в моем хранилище доверенных сертификатов, и после установки -Djavax.net.debug=all я вижу, что хранилище доверенных сертификатов инициализировано и есть доверенный сертификат:

trustStore is: test.truststore
trustStore type is : jks
trustStore provider is : 
init truststore
adding as trusted cert:
Subject: CN=Test Root, OU=test, O=test, C=us
Issuer:  CN=Test Root, OU=test, O=test, C=us
Algorithm: RSA; Serial number: 0x1
Valid from Thu Sep 05 14:49:45 GMT+00:00 2013 until Sun Sep 05 14:49:45 GMT+00:00 2021

Далее я вижу в цепочке сертификатов сервера доверенный сертификат:

chain [2] = [
[
  Version: V3
  Subject: CN=Test Root, OU=test, O=test, C=us
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

  Key:  Sun RSA public key, 2048 bits
  modulus: 259491476017...{etc}
  public exponent: 65537
  Validity: [From: Thu Sep 05 14:49:45 GMT+00:00 2013,
               To: Sun Sep 05 14:49:45 GMT+00:00 2021]
  Issuer: CN=Test Root, OU=test, O=test, C=us
  SerialNumber: [    01]

Но по какой-то причине рукопожатие все равно не удается:

%% Invalidated:  [Session-1, TLS_RSA_WITH_AES_256_CBC_SHA]
Thread-2, SEND TLSv1 ALERT:  fatal, description = certificate_unknown
Thread-2, WRITE: TLSv1 Alert, length = 2
[Raw write]: length = 7
0000: 15 03 01 00 02 02 2E                               .......
Thread-2, called closeSocket()
Thread-2, handling exception: javax.net.ssl.SSLHandshakeException:         sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: non-null policy tree required and policy tree is null
Thread-2, IOException in getSession():  javax.net.ssl.SSLHandshakeException:   sun.security.validator.ValidatorException: PKIX path validation failed:   java.security.cert.CertPathValidatorException: non-null policy tree required and policy tree is null

Что означает это «требуется ненулевое дерево политик, а дерево политик равно null»?


person Lucky Dog    schedule 31.01.2014    source источник
comment
Без примера рабочего кода ответить на ваш вопрос будет сложно. Разместите свой код в виде минимального примера, демонстрирующего вашу проблему.   -  person Duncan Jones    schedule 31.01.2014


Ответы (1)


Я видел эту проблему, когда приложение пыталось проверить цепочку с Require Explicit Policy:0 (как это делают посредники Министерства обороны США) и включало самозаверяющий сертификат как в certPath, так и в PKIXParameters в качестве якоря доверия. Похожий на:

CertPath certPath = CertificateFactory.getInstance("X.509").generateCertPath(chain);
X509Certificate ca = (X509Certificate)chain.get(chain.size() - 1);
TrustAnchor trustAnchor = new TrustAnchor((X509Certificate)ca, null);
PKIXParameters params = new PKIXParameters(Collections.singleton(trustAnchor));

Я не пробовал это с SSLSocket, но я предполагаю, что вы можете увидеть это, если сервер отправит корень (на самом деле они не должны). Я думаю, что правильным исправлением было бы проверить, является ли последний сертификат самовыданным (getSubjectX500Principal() equals getIssuerX500Principal()), и удалить его из цепочки, прежде чем вызывать для него валидатор. Похожий на:

if (ca.getSubjectX500Principal().equals(ca.getIssuerX500Principal())) {
  chain.remove(ca);
}

Не проверено с SSL, но это то, что сработало для меня при проверке закрытого ключа + чтение полной цепочки из файла PEM.

Трассировка стека BouncyCastle по сравнению с провайдером солнца:

java.security.cert.CertPathValidatorException: non-null policy tree required and policy tree is null
        at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135)
        at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:233)
        at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:141)
        at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:80)
        at java.security.cert.CertPathValidator.validate(CertPathValidator.java:292)
        at test.main(test.java:52)
Caused by: java.security.cert.CertPathValidatorException: non-null policy tree required and policy tree is null
        at sun.security.provider.certpath.PolicyChecker.processPolicies(PolicyChecker.java:572)
        at sun.security.provider.certpath.PolicyChecker.checkPolicy(PolicyChecker.java:225)
        at sun.security.provider.certpath.PolicyChecker.check(PolicyChecker.java:180)
        at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:125)
        ... 5 more
org.bouncycastle.jce.exception.ExtCertPathValidatorException: No valid policy tree found when one expected.
        at org.bouncycastle.jce.provider.RFC3280CertPathUtilities.processCertF(Unknown Source)
        at org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(Unknown Source)
        at java.security.cert.CertPathValidator.validate(CertPathValidator.java:292)
        at test.main(test.java:53)
person neutronscott    schedule 19.06.2020