Я пытаюсь запросить новый сертификат по протоколу EST с URL-адреса службы тестирования EST «https://testrfc7030.com/». Для этого программа использует Bouncy Castle.
Я уже настроил ТА сервиса EST и полученный от них сертификат клиента. Я также использую поставщика BC JSSE, чтобы получить доступ к значению привязки канала «tls-unique».
eSTService = new JsseESTServiceBuilder(Config.CredAdmin.caHost, trustManagers)
.withKeyManagers(keyManagers)
.withProvider(BouncyCastleJsseProvider.PROVIDER_NAME)
.withChannelBindingProvider(new ChannelBindingProvider() {
//Use an anonymous binding provider that supports linking
//Identity and POP Information (RFC7030, Section 3.5.), that
//relies on Channel Bindings for TLS (RFC5929) using "tls-unique".
public boolean canAccessChannelBinding(Socket sock) {
boolean ret = sock instanceof BCSSLSocket;
if (!ret)
//should never happen
MyUtils.LambdaLogger.error("Can't get channel binding value, check if BouncyCastleJsseProvider could be loaded.");
return ret;
}
public byte[] getChannelBinding(Socket sock, String binding) {
BCSSLConnection bcon = ((BCSSLSocket)sock).getConnection();
if (bcon == null) {
//should never happen
MyUtils.LambdaLogger.error("Can't get \"%s\" channel binding value, check if BouncyCastleJsseProvider could be loaded.", binding);
return null;
}
byte[] ret = bcon.getChannelBinding(binding);
MyUtils.LambdaLogger.debug("retrieved %d bytes \"%s\" channel binding value", ret.length, binding);
return ret;
}
})
.build();
и
Security.addProvider(new BouncyCastleJsseProvider());
Когда я настраиваю порт службы EST 9443 — для этого требуется мой клиентский сертификат, но не привязка канала TLS — я получаю новый сертификат:
Однако, когда я настраиваю порт 443 — для этого также требуется привязка канала TLS — хотя я получаю 12 байтов «tls-unique» от BC JSSE, они не будут приняты службой EST testrfc7030.com, поэтому он дает мне HTTP 401 — Неавторизованный:
Моя проблема в том, что я не знаю, что не так:
У кого-нибудь есть реализация, работающая с EST-сервисом «testrfc7030.com:443», арт имеет хотя бы представление, что не так?
---Обновление 1---
Я создаю ContentSigner
следующим образом:
ContentSigner signer =
new JcaContentSignerBuilder(MyUtils.Crypto.sha256WithRSAEncryption)
.setProvider(BouncyCastleProvider.PROVIDER_NAME)
.build(keyPair.getPrivate());
и csrBuilder
:
PKCS10CertificationRequestBuilder csrBuilder =
new PKCS10CertificationRequestBuilder(
new X500Name(subjectDN),
SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded()));
csrBuilder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extGen.generate());
с
ExtensionsGenerator extGen = new ExtensionsGenerator();
...
Затем мы используем это следующим образом:
EnrollmentResponse resp = eSTService.simpleEnrollPoP(false, cb.csrBuilder, cb.signer, null);
Я добавил обновление в исходный пост. Лично я считаю, что что-то не так с кодировкой Base64 «tls-unique» в github.com/bcgit/bc-java/blob/….
Судя по моему чтению testrfc7030.com, порт 443 выглядит так, как будто ему требуется HTTP-аутентификация пользователя, в то время как в вашем примере вызов simpleEnrollPop не указывает ее. JcaHttpAuthBuilder можно использовать для создания подходящего объекта аутентификации.
Благодарю вас! Это решило вопрос. Результат нашего теста testrfc7030.com: Порт 443 — требуется HTTP-аутентификация пользователя + POP-связь (первый здесь не был так ясен для меня на их веб-странице, спасибо @PeterDettman за очистку) Порт 8443: требуется HTTP-пользователь auth, но без удостоверения Связывание POP Порт 9443: требуется аутентификация пользователя с сертификатом клиента (полученным через порт 8443 или порт 443), но без удостоверения Связывание POP удостоверение Связывание POP = привязка канала TLS
Основываясь на отзывах Питера, мы смогли решить эту проблему следующим образом:
//just for testrfc7030.com
ESTAuth auth = new JcaHttpAuthBuilder(null, "estuser", "estpwd".toCharArray())
.setNonceGenerator(new SecureRandom())
.setProvider("BC")
.build();
EnrollmentResponse resp = eSTService.simpleEnrollPoP(false, cb.csrBuilder, cb.signer, auth);
Выяснилось, что testrfc3070 требует следующих схем аутентификации:
привязка идентификатора POP = привязка канала TLS
Маловероятно, что tls-unique является проблемой, так как это просто копия первого сообщения Finished, которое в любом случае должно быть правильным, чтобы рукопожатие работало. Можете ли вы проверить (показать), как вы создаете ContentSigner для (предполагаемого) вызова simpleEnrollPoP?