У меня есть требование, когда можно предоставить промежуточный ЦС для доверия, но не ЦС, которые его подписали.И используя это в качестве хранилища доверия, я хотел бы иметь возможность доверять серверу SSL, который имеет сертификат, подписанный этим промежуточным центром сертификации.Реализация по умолчанию предполагает построение всей цепочки, пока не будет найден доверенный самозаверяющий корневой CA.Я верю, что именно так основана вся платформа X509.Но по определенным причинам я могу предоставить только промежуточный CA.
Код - это обычное создание SSLContext:
// keystore part is pseudocode to make a point
KeyStore keyStore = someWayToGenerateKeyStore;
keyStore.add(intermediateCa);
//keyStore.add(rootCaThatSignedTheIntermediateCaAbove); it will work if I add this. But I don't want to for reasons.
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(keyStore);
SSLContext ctx = SSLContext.getInstance("TLSv1.2");
ctx.init(new KeyManager[], tmf.getTrustManagers(), new SecureRandom());
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setSslContext(ctx);
client = new WebSocketClient(sslContextFactory);
В OpenSSL есть параметр, который, похоже, работает.Поэтому я полагаю, что это не совсем неортодоксальный подход.
openssl verify -CApath /dev/null -partial_chain -trusted g1 g0
Есть две причины, по которым необходимо иметь только промежуточный CA в доверенном хранилище.
- Это облегчаетобойти один доверенный сертификат в системе, который в настоящее время зависит от одного самозаверяющего сертификата CA.Связь и настройка многих компонентов ожидают одного сертификата в данный момент и изменения, которые потребуют значительного рефакторинга.
- Мы хотим убедиться, что доверяем только сертификату, подписанному данным промежуточным сертификатом CA.Если мы добавим другие сертификаты ЦС в цепочке в хранилище доверенных сертификатов, реализация SSL будет доверять любому сертификату, подписанному другими ЦС, которого мы также хотим избежать.Возможно, есть и другие способы сделать это, например, проверить isser_dn, но я бы хотел изучить другие подходы.