All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.quarkus.pulsar.QuarkusPulsarKeyStoreAuthentication Maven / Gradle / Ivy

There is a newer version: 3.15.0
Show newest version
package io.quarkus.pulsar;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.Map;
import java.util.stream.Stream;

import org.apache.pulsar.client.api.Authentication;
import org.apache.pulsar.client.api.AuthenticationDataProvider;
import org.apache.pulsar.client.api.PulsarClientException;

import io.quarkus.tls.TlsConfiguration;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.KeyStoreOptionsBase;

public class QuarkusPulsarKeyStoreAuthentication implements Authentication {
    public static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----";
    public static final String END_CERT = "-----END CERTIFICATE-----";
    public static final String LINE_SEPARATOR = System.getProperty("line.separator", "\n");

    private final TlsConfiguration configuration;

    public QuarkusPulsarKeyStoreAuthentication(TlsConfiguration configuration) {
        this.configuration = configuration;
    }

    @Override
    public String getAuthMethodName() {
        return "quarkus-pulsar";
    }

    @Override
    public void configure(Map authParams) {

    }

    @Override
    public void start() throws PulsarClientException {

    }

    @Override
    public void close() throws IOException {

    }

    @Override
    public AuthenticationDataProvider getAuthData() throws PulsarClientException {
        try {
            // Extract keystore password
            String keyStorePwd = ((KeyStoreOptionsBase) configuration.getKeyStoreOptions()).getPassword();
            // Certificates
            KeyStore keyStore = configuration.getKeyStore();
            String alias = keyStore.aliases().nextElement();
            // TODO do we need to handle certificate chains here?
            X509Certificate cert = (X509Certificate) keyStore.getCertificate(alias);
            X509Certificate[] certificates = Stream.of(cert).toArray(X509Certificate[]::new);

            // Private key
            KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias,
                    new KeyStore.PasswordProtection(keyStorePwd.toCharArray()));
            PrivateKey privateKey = privateKeyEntry.getPrivateKey();

            // Trust store certificate
            KeyStore trustStore = configuration.getTrustStore();
            String trustAlias = trustStore.aliases().nextElement();
            Certificate trustStoreCertificate = trustStore.getCertificate(trustAlias);
            Buffer formatCrtFileContents = formatCrtFileContents(trustStoreCertificate);

            return new QuarkusPulsarAuthenticationData(certificates, privateKey, formatCrtFileContents);
        } catch (Exception e) {
            throw new PulsarClientException(e);
        }
    }

    public static Buffer formatCrtFileContents(Certificate certificate) throws CertificateEncodingException {
        Buffer buffer = Buffer.buffer();
        final Base64.Encoder encoder = Base64.getMimeEncoder(64, LINE_SEPARATOR.getBytes());

        buffer.appendString(BEGIN_CERT)
                .appendString(LINE_SEPARATOR)
                .appendBytes(encoder.encode(certificate.getEncoded()))
                .appendString(LINE_SEPARATOR)
                .appendString(END_CERT);
        return buffer;
    }

    private static class QuarkusPulsarAuthenticationData implements AuthenticationDataProvider {

        private final Certificate[] certs;
        private final PrivateKey privateKey;
        private final InputStream trustStoreStream;

        public QuarkusPulsarAuthenticationData(Certificate[] certs, PrivateKey privateKey, Buffer trustStore) {
            this.certs = certs;
            this.privateKey = privateKey;
            this.trustStoreStream = new ByteArrayInputStream(trustStore.getBytes());
        }

        public boolean hasDataForTls() {
            return true;
        }

        @Override
        public Certificate[] getTlsCertificates() {
            return certs;
        }

        @Override
        public PrivateKey getTlsPrivateKey() {
            return privateKey;
        }

        @Override
        public InputStream getTlsTrustStoreStream() {
            return trustStoreStream;
        }

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy