Search in sources :

Example 1 with TlsCertificateAuthorityRequest

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);
    }
}
Also used : CloseableHttpClient(org.apache.http.impl.client.CloseableHttpClient) HttpPost(org.apache.http.client.methods.HttpPost) JcaPKCS10CertificationRequest(org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest) TlsCertificateAuthorityResponse(org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityResponse) ArrayList(java.util.ArrayList) HttpClientBuilder(org.apache.http.impl.client.HttpClientBuilder) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) IOException(java.io.IOException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) ByteArrayEntity(org.apache.http.entity.ByteArrayEntity) HttpHost(org.apache.http.HttpHost) BoundedInputStream(org.apache.commons.io.input.BoundedInputStream) TlsCertificateAuthorityRequest(org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityRequest) CloseableHttpResponse(org.apache.http.client.methods.CloseableHttpResponse) StringReader(java.io.StringReader) SSLContextBuilder(org.apache.http.ssl.SSLContextBuilder) TrustSelfSignedStrategy(org.apache.http.conn.ssl.TrustSelfSignedStrategy)

Example 2 with TlsCertificateAuthorityRequest

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());
}
Also used : TlsCertificateAuthorityRequest(org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityRequest) Test(org.junit.Test)

Example 3 with TlsCertificateAuthorityRequest

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());
}
Also used : TlsCertificateAuthorityRequest(org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityRequest) Test(org.junit.Test)

Example 4 with TlsCertificateAuthorityRequest

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);
    }
}
Also used : ServletException(javax.servlet.ServletException) JcaPKCS10CertificationRequest(org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest) TlsCertificateAuthorityResponse(org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityResponse) TlsCertificateAuthorityRequest(org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityRequest) BoundedReader(org.apache.commons.io.input.BoundedReader) X509Certificate(java.security.cert.X509Certificate) ServletException(javax.servlet.ServletException) IOException(java.io.IOException)

Example 5 with TlsCertificateAuthorityRequest

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);
}
Also used : HttpPost(org.apache.http.client.methods.HttpPost) JcaPKCS10CertificationRequest(org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest) KeyPair(java.security.KeyPair) ByteArrayOutputStream(java.io.ByteArrayOutputStream) StatusLine(org.apache.http.StatusLine) Field(java.lang.reflect.Field) ByteArrayEntity(org.apache.http.entity.ByteArrayEntity) HttpHost(org.apache.http.HttpHost) TlsCertificateAuthorityRequest(org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityRequest) CloseableHttpResponse(org.apache.http.client.methods.CloseableHttpResponse) TlsConfig(org.apache.nifi.toolkit.tls.configuration.TlsConfig) ArrayList(java.util.ArrayList) List(java.util.List) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Before(org.junit.Before)

Aggregations

TlsCertificateAuthorityRequest (org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityRequest)7 Test (org.junit.Test)4 X509Certificate (java.security.cert.X509Certificate)3 JcaPKCS10CertificationRequest (org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest)3 IOException (java.io.IOException)2 StringReader (java.io.StringReader)2 ArrayList (java.util.ArrayList)2 HttpHost (org.apache.http.HttpHost)2 CloseableHttpResponse (org.apache.http.client.methods.CloseableHttpResponse)2 HttpPost (org.apache.http.client.methods.HttpPost)2 ByteArrayEntity (org.apache.http.entity.ByteArrayEntity)2 TlsCertificateAuthorityResponse (org.apache.nifi.toolkit.tls.service.dto.TlsCertificateAuthorityResponse)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 Field (java.lang.reflect.Field)1 KeyPair (java.security.KeyPair)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 List (java.util.List)1 ServletException (javax.servlet.ServletException)1 BoundedInputStream (org.apache.commons.io.input.BoundedInputStream)1