use of org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityRequest 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.TlsCertificateAuthorityRequest in project nifi by apache.
the class TlsCertificateAuthorityServiceHandlerTest method testNoCsr.
@Test
public void testNoCsr() throws IOException, ServletException {
tlsCertificateAuthorityRequest = new TlsCertificateAuthorityRequest(testHmac, null);
tlsCertificateAuthorityServiceHandler.handle(null, baseRequest, httpServletRequest, httpServletResponse);
assertEquals(Response.SC_BAD_REQUEST, statusCode);
assertEquals(TlsCertificateAuthorityServiceHandler.CSR_FIELD_MUST_BE_SET, getResponse().getError());
}
use of org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityRequest in project nifi by apache.
the class TlsCertificateAuthorityServiceHandlerTest method testForbidden.
@Test
public void testForbidden() throws IOException, ServletException, NoSuchAlgorithmException, CRMFException, NoSuchProviderException, InvalidKeyException {
tlsCertificateAuthorityRequest = new TlsCertificateAuthorityRequest("badHmac".getBytes(StandardCharsets.UTF_8), testPemEncodedCsr);
tlsCertificateAuthorityServiceHandler.handle(null, baseRequest, httpServletRequest, httpServletResponse);
assertEquals(Response.SC_FORBIDDEN, statusCode);
assertEquals(TlsCertificateAuthorityServiceHandler.FORBIDDEN, getResponse().getError());
}
use of org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityRequest in project nifi by apache.
the class TlsCertificateAuthorityServiceHandler method handle.
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
try {
TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest = objectMapper.readValue(new BoundedReader(request.getReader(), 1024 * 1024), TlsCertificateAuthorityRequest.class);
if (!tlsCertificateAuthorityRequest.hasHmac()) {
writeResponse(objectMapper, request, response, new TlsCertificateAuthorityResponse(HMAC_FIELD_MUST_BE_SET), Response.SC_BAD_REQUEST);
return;
}
if (!tlsCertificateAuthorityRequest.hasCsr()) {
writeResponse(objectMapper, request, response, new TlsCertificateAuthorityResponse(CSR_FIELD_MUST_BE_SET), Response.SC_BAD_REQUEST);
return;
}
JcaPKCS10CertificationRequest jcaPKCS10CertificationRequest = TlsHelper.parseCsr(tlsCertificateAuthorityRequest.getCsr());
byte[] expectedHmac = TlsHelper.calculateHMac(token, jcaPKCS10CertificationRequest.getPublicKey());
if (MessageDigest.isEqual(expectedHmac, tlsCertificateAuthorityRequest.getHmac())) {
String dn = jcaPKCS10CertificationRequest.getSubject().toString();
if (logger.isInfoEnabled()) {
logger.info("Received CSR with DN " + dn);
}
X509Certificate x509Certificate = CertificateUtils.generateIssuedCertificate(dn, jcaPKCS10CertificationRequest.getPublicKey(), CertificateUtils.getExtensionsFromCSR(jcaPKCS10CertificationRequest), caCert, keyPair, signingAlgorithm, days);
writeResponse(objectMapper, request, response, new TlsCertificateAuthorityResponse(TlsHelper.calculateHMac(token, caCert.getPublicKey()), TlsHelper.pemEncodeJcaObject(x509Certificate)), Response.SC_OK);
return;
} else {
writeResponse(objectMapper, request, response, new TlsCertificateAuthorityResponse(FORBIDDEN), Response.SC_FORBIDDEN);
return;
}
} catch (Exception e) {
throw new ServletException("Server error");
} finally {
baseRequest.setHandled(true);
}
}
use of org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityRequest in project nifi by apache.
the class TlsCertificateSigningRequestPerformerTest method setup.
@Before
public void setup() throws GeneralSecurityException, OperatorCreationException, IOException {
objectMapper = new ObjectMapper();
keyPair = TlsHelper.generateKeyPair(TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM, TlsConfig.DEFAULT_KEY_SIZE);
testToken = "testTokenTestToken";
testCaHostname = "testCaHostname";
testPort = 8993;
certificates = new ArrayList<>();
when(tlsClientConfig.getToken()).thenReturn(testToken);
when(tlsClientConfig.getCaHostname()).thenReturn(testCaHostname);
when(tlsClientConfig.getDn()).thenReturn(new TlsConfig().calcDefaultDn(testCaHostname));
when(tlsClientConfig.getPort()).thenReturn(testPort);
when(tlsClientConfig.createCertificateSigningRequestPerformer()).thenReturn(tlsCertificateSigningRequestPerformer);
when(tlsClientConfig.getSigningAlgorithm()).thenReturn(TlsConfig.DEFAULT_SIGNING_ALGORITHM);
JcaPKCS10CertificationRequest jcaPKCS10CertificationRequest = TlsHelper.generateCertificationRequest(tlsClientConfig.getDn(), null, keyPair, TlsConfig.DEFAULT_SIGNING_ALGORITHM);
String testCsrPem = TlsHelper.pemEncodeJcaObject(jcaPKCS10CertificationRequest);
when(httpClientBuilderSupplier.get()).thenReturn(httpClientBuilder);
when(httpClientBuilder.build()).thenAnswer(invocation -> {
Field sslSocketFactory = HttpClientBuilder.class.getDeclaredField("sslSocketFactory");
sslSocketFactory.setAccessible(true);
Object o = sslSocketFactory.get(httpClientBuilder);
Field field = TlsCertificateAuthorityClientSocketFactory.class.getDeclaredField("certificates");
field.setAccessible(true);
((List<X509Certificate>) field.get(o)).addAll(certificates);
return closeableHttpClient;
});
StatusLine statusLine = mock(StatusLine.class);
when(statusLine.getStatusCode()).thenAnswer(i -> statusCode);
when(closeableHttpClient.execute(eq(new HttpHost(testCaHostname, testPort, "https")), any(HttpPost.class))).thenAnswer(invocation -> {
HttpPost httpPost = (HttpPost) invocation.getArguments()[1];
TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest = objectMapper.readValue(httpPost.getEntity().getContent(), TlsCertificateAuthorityRequest.class);
assertEquals(tlsCertificateAuthorityRequest.getCsr(), testCsrPem);
CloseableHttpResponse closeableHttpResponse = mock(CloseableHttpResponse.class);
when(closeableHttpResponse.getEntity()).thenAnswer(i -> {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
objectMapper.writeValue(byteArrayOutputStream, tlsCertificateAuthorityResponse);
return new ByteArrayEntity(byteArrayOutputStream.toByteArray());
});
when(closeableHttpResponse.getStatusLine()).thenReturn(statusLine);
return closeableHttpResponse;
});
KeyPair caKeyPair = TlsHelper.generateKeyPair(TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM, TlsConfig.DEFAULT_KEY_SIZE);
caCertificate = CertificateUtils.generateSelfSignedX509Certificate(caKeyPair, "CN=fakeCa", TlsConfig.DEFAULT_SIGNING_ALGORITHM, TlsConfig.DEFAULT_DAYS);
testHmac = TlsHelper.calculateHMac(testToken, caCertificate.getPublicKey());
signedCsr = CertificateUtils.generateIssuedCertificate(jcaPKCS10CertificationRequest.getSubject().toString(), jcaPKCS10CertificationRequest.getPublicKey(), caCertificate, caKeyPair, TlsConfig.DEFAULT_SIGNING_ALGORITHM, TlsConfig.DEFAULT_DAYS);
testSignedCsr = TlsHelper.pemEncodeJcaObject(signedCsr);
tlsCertificateSigningRequestPerformer = new TlsCertificateSigningRequestPerformer(httpClientBuilderSupplier, tlsClientConfig);
}
Aggregations