use of org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityResponse in project nifi by apache.
the class TlsCertificateSigningRequestPerformer method perform.
/**
* Submits a CSR to the Certificate authority, checks the resulting hmac, and returns the chain if everything succeeds
*
* @param keyPair the keypair to generate the csr for
* @throws IOException if there is a problem during the process
* @return the resulting certificate chain
*/
public X509Certificate[] perform(KeyPair keyPair) throws IOException {
try {
List<X509Certificate> certificates = new ArrayList<>();
HttpClientBuilder httpClientBuilder = httpClientBuilderSupplier.get();
SSLContextBuilder sslContextBuilder = SSLContextBuilder.create();
sslContextBuilder.useProtocol("TLSv1.2");
// We will be validating that we are talking to the correct host once we get the response's hmac of the token and public key of the ca
sslContextBuilder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
httpClientBuilder.setSSLSocketFactory(new TlsCertificateAuthorityClientSocketFactory(sslContextBuilder.build(), caHostname, certificates));
String jsonResponseString;
int responseCode;
try (CloseableHttpClient client = httpClientBuilder.build()) {
JcaPKCS10CertificationRequest request = TlsHelper.generateCertificationRequest(dn, domainAlternativeNames, keyPair, signingAlgorithm);
TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest = new TlsCertificateAuthorityRequest(TlsHelper.calculateHMac(token, request.getPublicKey()), TlsHelper.pemEncodeJcaObject(request));
HttpPost httpPost = new HttpPost();
httpPost.setEntity(new ByteArrayEntity(objectMapper.writeValueAsBytes(tlsCertificateAuthorityRequest)));
if (logger.isInfoEnabled()) {
logger.info("Requesting certificate with dn " + dn + " from " + caHostname + ":" + port);
}
try (CloseableHttpResponse response = client.execute(new HttpHost(caHostname, port, "https"), httpPost)) {
jsonResponseString = IOUtils.toString(new BoundedInputStream(response.getEntity().getContent(), 1024 * 1024), StandardCharsets.UTF_8);
responseCode = response.getStatusLine().getStatusCode();
}
}
if (responseCode != Response.SC_OK) {
throw new IOException(RECEIVED_RESPONSE_CODE + responseCode + " with payload " + jsonResponseString);
}
if (certificates.size() != 1) {
throw new IOException(EXPECTED_ONE_CERTIFICATE);
}
TlsCertificateAuthorityResponse tlsCertificateAuthorityResponse = objectMapper.readValue(jsonResponseString, TlsCertificateAuthorityResponse.class);
if (!tlsCertificateAuthorityResponse.hasHmac()) {
throw new IOException(EXPECTED_RESPONSE_TO_CONTAIN_HMAC);
}
X509Certificate caCertificate = certificates.get(0);
byte[] expectedHmac = TlsHelper.calculateHMac(token, caCertificate.getPublicKey());
if (!MessageDigest.isEqual(expectedHmac, tlsCertificateAuthorityResponse.getHmac())) {
throw new IOException(UNEXPECTED_HMAC_RECEIVED_POSSIBLE_MAN_IN_THE_MIDDLE);
}
if (!tlsCertificateAuthorityResponse.hasCertificate()) {
throw new IOException(EXPECTED_RESPONSE_TO_CONTAIN_CERTIFICATE);
}
X509Certificate x509Certificate = TlsHelper.parseCertificate(new StringReader(tlsCertificateAuthorityResponse.getPemEncodedCertificate()));
x509Certificate.verify(caCertificate.getPublicKey());
if (logger.isInfoEnabled()) {
logger.info("Got certificate with dn " + x509Certificate.getSubjectX500Principal());
}
return new X509Certificate[] { x509Certificate, caCertificate };
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOException(e);
}
}
use of org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityResponse in project nifi by apache.
the class TlsCertificateSigningRequestPerformerTest method testNoHmac.
@Test
public void testNoHmac() throws Exception {
certificates.add(caCertificate);
statusCode = Response.SC_OK;
tlsCertificateAuthorityResponse = new TlsCertificateAuthorityResponse(null, testSignedCsr);
try {
tlsCertificateSigningRequestPerformer.perform(keyPair);
fail("Expected IOE");
} catch (IOException e) {
assertEquals(TlsCertificateSigningRequestPerformer.EXPECTED_RESPONSE_TO_CONTAIN_HMAC, e.getMessage());
}
}
use of org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityResponse in project nifi by apache.
the class TlsCertificateSigningRequestPerformerTest method testBadHmac.
@Test
public void testBadHmac() throws Exception {
certificates.add(caCertificate);
statusCode = Response.SC_OK;
tlsCertificateAuthorityResponse = new TlsCertificateAuthorityResponse("badHmac".getBytes(StandardCharsets.UTF_8), testSignedCsr);
try {
tlsCertificateSigningRequestPerformer.perform(keyPair);
fail("Expected IOE");
} catch (IOException e) {
assertEquals(TlsCertificateSigningRequestPerformer.UNEXPECTED_HMAC_RECEIVED_POSSIBLE_MAN_IN_THE_MIDDLE, e.getMessage());
}
}
use of org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityResponse in project nifi by apache.
the class TlsCertificateSigningRequestPerformerTest method testBadStatusCode.
@Test
public void testBadStatusCode() throws Exception {
statusCode = Response.SC_FORBIDDEN;
tlsCertificateAuthorityResponse = new TlsCertificateAuthorityResponse();
try {
tlsCertificateSigningRequestPerformer.perform(keyPair);
fail("Expected IOE");
} catch (IOException e) {
assertTrue(e.getMessage().startsWith(TlsCertificateSigningRequestPerformer.RECEIVED_RESPONSE_CODE + statusCode));
}
}
use of org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityResponse in project nifi by apache.
the class TlsCertificateSigningRequestPerformerTest method test0CertSize.
@Test
public void test0CertSize() throws Exception {
statusCode = Response.SC_OK;
tlsCertificateAuthorityResponse = new TlsCertificateAuthorityResponse();
try {
tlsCertificateSigningRequestPerformer.perform(keyPair);
fail("Expected IOE");
} catch (IOException e) {
assertEquals(TlsCertificateSigningRequestPerformer.EXPECTED_ONE_CERTIFICATE, e.getMessage());
}
}
Aggregations