У меня есть требование, согласно которому можно предоставить промежуточный ЦС, которому можно доверять, но не ЦС, которые его подписали. И, используя это как хранилище доверия, я хотел бы иметь возможность доверять серверу SSL, у которого есть сертификат, подписанный этим промежуточным центром сертификации. Реализация по умолчанию предполагает построение всей цепочки до тех пор, пока не будет найден доверенный самозаверяющий корневой ЦС. Я считаю, что на этом основана вся платформа X509. Но по определенным причинам я могу предоставить только промежуточный ЦС.
Код представляет собой обычное создание 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
Есть две причины для требования иметь только промежуточный ЦС в хранилище доверенных сертификатов.
- Это упрощает передачу одного доверенного сертификата по системе, которая в настоящее время зависит от одного самозаверяющего сертификата ЦС. Для связи и настройки многих компонентов на данный момент требуется один сертификат, и его изменение потребует значительного рефакторинга.
- Мы хотим убедиться, что доверяем только сертификату, подписанному данным промежуточным сертификатом ЦС. Если мы добавим другие сертификаты ЦС в цепочке в хранилище доверенных сертификатов, реализация SSL будет доверять любому сертификату, подписанному другими ЦС, которых мы также хотим избежать. Вероятно, есть и другие способы сделать это, например, проверить issuer_dn, но я хотел бы изучить другие подходы.