You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2017/01/30 15:40:34 UTC

[13/30] ambari git commit: AMBARI-19723 Log Search portal not working if only solr needs SSL connection (mgergely)

AMBARI-19723 Log Search portal not working if only solr needs SSL connection (mgergely)

Change-Id: Iebb2ef076dd4f75af73757ab3f08f250c654df69


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/015d4046
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/015d4046
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/015d4046

Branch: refs/heads/branch-dev-patch-upgrade
Commit: 015d404604da164aa939635b7835a9551321cc5e
Parents: 86fbb38
Author: Miklos Gergely <mg...@hortonworks.com>
Authored: Sun Jan 29 13:24:00 2017 +0100
Committer: Miklos Gergely <mg...@hortonworks.com>
Committed: Sun Jan 29 13:24:00 2017 +0100

----------------------------------------------------------------------
 .../ambari-logsearch-portal/pom.xml             |   5 +
 .../org/apache/ambari/logsearch/LogSearch.java  |  98 +------------
 .../apache/ambari/logsearch/util/FileUtil.java  |  26 ++++
 .../apache/ambari/logsearch/util/SSLUtil.java   | 141 +++++++++++++++----
 4 files changed, 148 insertions(+), 122 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/015d4046/ambari-logsearch/ambari-logsearch-portal/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/pom.xml b/ambari-logsearch/ambari-logsearch-portal/pom.xml
index 61dcb37..32d4e2c 100755
--- a/ambari-logsearch/ambari-logsearch-portal/pom.xml
+++ b/ambari-logsearch/ambari-logsearch-portal/pom.xml
@@ -786,5 +786,10 @@
       <artifactId>bcprov-jdk15on</artifactId>
       <version>1.55</version>
     </dependency>
+    <dependency>
+      <groupId>org.bouncycastle</groupId>
+      <artifactId>bcpkix-jdk15on</artifactId>
+      <version>1.55</version>
+    </dependency>
   </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/ambari/blob/015d4046/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/LogSearch.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/LogSearch.java b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/LogSearch.java
index 88cc8bb..70053d2 100644
--- a/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/LogSearch.java
+++ b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/LogSearch.java
@@ -18,17 +18,12 @@
  */
 package org.apache.ambari.logsearch;
 
-import java.io.File;
 import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.ServerSocket;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
-import java.security.KeyPair;
-import java.security.KeyStore;
-import java.security.Security;
-import java.security.cert.X509Certificate;
 import java.util.EnumSet;
 
 import org.apache.ambari.logsearch.common.ManageStartEndTime;
@@ -36,12 +31,7 @@ import org.apache.ambari.logsearch.common.PropertiesHelper;
 import org.apache.ambari.logsearch.conf.ApplicationConfig;
 import org.apache.ambari.logsearch.util.SSLUtil;
 import org.apache.ambari.logsearch.web.listener.LogSearchSessionListener;
-import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.StringUtils;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.taskdefs.Chmod;
-import org.apache.tools.ant.types.FileSet;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.eclipse.jetty.server.Connector;
 import org.eclipse.jetty.server.HttpConfiguration;
 import org.eclipse.jetty.server.HttpConnectionFactory;
@@ -73,8 +63,6 @@ public class LogSearch {
   private static final Logger LOG = LoggerFactory.getLogger(LogSearch.class);
 
   private static final String LOGSEARCH_PROTOCOL_PROP = "logsearch.protocol";
-  private static final String LOGSEARCH_CERT_FOLDER_LOCATION = "logsearch.cert.folder.location";
-  private static final String LOGSEARCH_CERT_ALGORITHM = "logsearch.cert.algorithm";
   private static final String HTTPS_PROTOCOL = "https";
   private static final String HTTP_PROTOCOL = "http";
   private static final String HTTPS_PORT = "61889";
@@ -84,15 +72,6 @@ public class LogSearch {
   private static final String ROOT_CONTEXT = "/";
   private static final Integer SESSION_TIMEOUT = 60 * 30;
 
-  private static final String LOGSEARCH_CERT_FILENAME = "logsearch.crt";
-  private static final String LOGSEARCH_KEYSTORE_FILENAME = "logsearch.jks";
-  private static final String LOGSEARCH_KEYSTORE_PRIVATE_KEY = "logsearch.private.key";
-  private static final String LOGSEARCH_KEYSTORE_PUBLIC_KEY = "logsearch.public.key";
-  private static final String LOGSEARCH_CERT_DEFAULT_ALGORITHM = "sha256WithRSAEncryption";
-
-  public static final String LOGSEARCH_CERT_DEFAULT_FOLDER = "/etc/ambari-logsearch-portal/conf/keys";
-  public static final String LOGSEARCH_KEYSTORE_DEFAULT_PASSWORD = "bigdata";
-
   public static void main(String[] argv) {
     LogSearch logSearch = new LogSearch();
     ManageStartEndTime.manage();
@@ -104,7 +83,8 @@ public class LogSearch {
   }
 
   public void run(String[] argv) throws Exception {
-    loadKeystore();
+    SSLUtil.ensureStorePasswords();
+    SSLUtil.loadKeystore();
     Server server = buildSever(argv);
     HandlerList handlers = new HandlerList();
     handlers.addHandler(createSwaggerContext());
@@ -113,11 +93,9 @@ public class LogSearch {
     server.setHandler(handlers);
     server.start();
 
-    LOG
-        .debug("============================Server Dump=======================================");
+    LOG.debug("============================Server Dump=======================================");
     LOG.debug(server.dump());
-    LOG
-        .debug("==============================================================================");
+    LOG.debug("==============================================================================");
     server.join();
   }
 
@@ -202,7 +180,7 @@ public class LogSearch {
   private URI findWebResourceBase() {
     URL fileCompleteUrl = Thread.currentThread().getContextClassLoader()
         .getResource(WEB_RESOURCE_FOLDER);
-    String errorMessage = "Web Resource Folder " + WEB_RESOURCE_FOLDER+ " not found in classpath";
+    String errorMessage = "Web Resource Folder " + WEB_RESOURCE_FOLDER + " not found in classpath";
     if (fileCompleteUrl != null) {
       try {
         return fileCompleteUrl.toURI().normalize();
@@ -238,70 +216,4 @@ public class LogSearch {
       }
     }
   }
-
-  /**
-   * Create keystore with keys and certificate (only if the keystore does not exist or if you have no permissions on the keystore file)
-   */
-  void loadKeystore() {
-    try {
-      String certFolder = PropertiesHelper.getProperty(LOGSEARCH_CERT_FOLDER_LOCATION, LOGSEARCH_CERT_DEFAULT_FOLDER);
-      String certAlgorithm = PropertiesHelper.getProperty(LOGSEARCH_CERT_ALGORITHM, LOGSEARCH_CERT_DEFAULT_ALGORITHM);
-      String certLocation = String.format("%s/%s", LOGSEARCH_CERT_DEFAULT_FOLDER, LOGSEARCH_CERT_FILENAME);
-      String keyStoreLocation = StringUtils.isNotEmpty(SSLUtil.getKeyStoreLocation()) ? SSLUtil.getKeyStoreLocation()
-        : String.format("%s/%s", LOGSEARCH_CERT_DEFAULT_FOLDER, LOGSEARCH_KEYSTORE_FILENAME);
-      char[] password = StringUtils.isNotEmpty(SSLUtil.getKeyStorePassword()) ?
-        SSLUtil.getKeyStorePassword().toCharArray() : LOGSEARCH_KEYSTORE_DEFAULT_PASSWORD.toCharArray();
-      boolean keyStoreFileExists = new File(keyStoreLocation).exists();
-      if (!keyStoreFileExists) {
-        createDefaultKeyFolder(certFolder);
-        LOG.warn("Keystore file ('{}') does not exist, creating new one. " +
-          "If the file exists, make sure you have proper permissions on that.", keyStoreLocation);
-        if (SSLUtil.isKeyStoreSpecified() && !"JKS".equalsIgnoreCase(SSLUtil.getKeyStoreType())) {
-          throw new RuntimeException(String.format("Keystore does not exist. Only JKS keystore can be auto generated. (%s)", keyStoreLocation));
-        }
-        LOG.info("SSL keystore is not specified. Generating it with certificate ... (using default format: JKS)");
-        Security.addProvider(new BouncyCastleProvider());
-        KeyPair keyPair = SSLUtil.createKeyPair("RSA", 2048);
-        File privateKeyFile = new File(String.format("%s/%s", certFolder, LOGSEARCH_KEYSTORE_PRIVATE_KEY));
-        if (!privateKeyFile.exists()) {
-          FileUtils.writeByteArrayToFile(privateKeyFile, keyPair.getPrivate().getEncoded());
-        }
-        File file = new File(String.format("%s/%s", certFolder, LOGSEARCH_KEYSTORE_PUBLIC_KEY));
-        if (!file.exists()) {
-          FileUtils.writeByteArrayToFile(file, keyPair.getPublic().getEncoded());
-        }
-        X509Certificate cert = SSLUtil.generateCertificate(certLocation, keyPair, certAlgorithm);
-        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
-        keyStore.load(null, password);
-        SSLUtil.setKeyAndCertInKeystore(cert, keyPair, keyStore, keyStoreLocation, password);
-        setPermissionOnCertFolder(certFolder);
-      }
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  private void createDefaultKeyFolder(String certFolder) {
-    File keyFolderDirectory = new File(certFolder);
-    if (!keyFolderDirectory.exists()) {
-      LOG.info("Default key dir does not exist ({}). Creating ...", certFolder);
-      boolean mkDirSuccess = keyFolderDirectory.mkdirs();
-      if (!mkDirSuccess) {
-        String errorMessage = String.format("Could not create directory %s", certFolder);
-        LOG.error(errorMessage);
-        throw new RuntimeException(errorMessage);
-      }
-    }
-  }
-
-  private void setPermissionOnCertFolder(String certFolder) {
-    Chmod chmod = new Chmod();
-    chmod.setProject(new Project());
-    FileSet fileSet = new FileSet();
-    fileSet.setDir(new File(certFolder));
-    fileSet.setIncludes("**");
-    chmod.addFileset(fileSet);
-    chmod.setPerm("600");
-    chmod.execute();
-  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/015d4046/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/util/FileUtil.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/util/FileUtil.java b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/util/FileUtil.java
index f7330fa..5d4efbc 100644
--- a/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/util/FileUtil.java
+++ b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/util/FileUtil.java
@@ -23,6 +23,9 @@ import java.io.File;
 import java.net.URL;
 
 import org.apache.log4j.Logger;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Chmod;
+import org.apache.tools.ant.types.FileSet;
 
 public class FileUtil {
   private static final Logger logger = Logger.getLogger(FileUtil.class);
@@ -43,4 +46,27 @@ public class FileUtil {
     return file;
   }
 
+  public static void createDirectory(String dirPath) {
+    File dir = new File(dirPath);
+    if (!dir.exists()) {
+      logger.info("Directory " + dirPath + " does not exist. Creating ...");
+      boolean mkDirSuccess = dir.mkdirs();
+      if (!mkDirSuccess) {
+        String errorMessage = String.format("Could not create directory %s", dirPath);
+        logger.error(errorMessage);
+        throw new RuntimeException(errorMessage);
+      }
+    }
+  }
+
+  public static void setPermissionOnDirectory(String dirPath, String permission) {
+    Chmod chmod = new Chmod();
+    chmod.setProject(new Project());
+    FileSet fileSet = new FileSet();
+    fileSet.setDir(new File(dirPath));
+    fileSet.setIncludes("**");
+    chmod.addFileset(fileSet);
+    chmod.setPerm(permission);
+    chmod.execute();
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/015d4046/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/util/SSLUtil.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/util/SSLUtil.java b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/util/SSLUtil.java
index e0111e7..ea3474f 100644
--- a/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/util/SSLUtil.java
+++ b/ambari-logsearch/ambari-logsearch-portal/src/main/java/org/apache/ambari/logsearch/util/SSLUtil.java
@@ -26,10 +26,20 @@ import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.Path;
-import org.bouncycastle.jce.X509Principal;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.x509.X509V3CertificateGenerator;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.bc.BcContentSignerBuilder;
+import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.crypto.params.RSAKeyParameters;
 import org.eclipse.jetty.util.ssl.SslContextFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -37,6 +47,7 @@ import org.slf4j.LoggerFactory;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.math.BigInteger;
 import java.net.InetAddress;
 import java.security.InvalidKeyException;
@@ -49,14 +60,13 @@ import java.security.SecureRandom;
 import java.security.Security;
 import java.security.SignatureException;
 import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
 import java.util.Date;
 
-import static org.apache.ambari.logsearch.LogSearch.LOGSEARCH_CERT_DEFAULT_FOLDER;
-import static org.apache.ambari.logsearch.LogSearch.LOGSEARCH_KEYSTORE_DEFAULT_PASSWORD;
-
 public class SSLUtil {
   private static final Logger LOG = LoggerFactory.getLogger(SSLUtil.class);
   
@@ -74,6 +84,18 @@ public class SSLUtil {
   private static final String TRUSTSTORE_PASSWORD_FILE = "ts_pass.txt";
   private static final String CREDENTIAL_STORE_PROVIDER_PATH = "hadoop.security.credential.provider.path";
 
+  private static final String LOGSEARCH_CERT_FOLDER_LOCATION = "logsearch.cert.folder.location";
+  private static final String LOGSEARCH_CERT_ALGORITHM = "logsearch.cert.algorithm";
+  
+  private static final String LOGSEARCH_CERT_FILENAME = "logsearch.crt";
+  private static final String LOGSEARCH_KEYSTORE_FILENAME = "logsearch.jks";
+  private static final String LOGSEARCH_KEYSTORE_PRIVATE_KEY = "logsearch.private.key";
+  private static final String LOGSEARCH_KEYSTORE_PUBLIC_KEY = "logsearch.public.key";
+  private static final String LOGSEARCH_CERT_DEFAULT_ALGORITHM = "sha256WithRSA";
+
+  private static final String LOGSEARCH_CERT_DEFAULT_FOLDER = "/etc/ambari-logsearch-portal/conf/keys";
+  private static final String LOGSEARCH_KEYSTORE_DEFAULT_PASSWORD = "bigdata";
+  
   private SSLUtil() {
     throw new UnsupportedOperationException();
   }
@@ -111,8 +133,6 @@ public class SSLUtil {
   }
   
   public static SslContextFactory getSslContextFactory() {
-    setPasswordIfSysPropIsEmpty(KEYSTORE_PASSWORD_ARG, KEYSTORE_PASSWORD_PROPERTY_NAME, KEYSTORE_PASSWORD_FILE);
-    setPasswordIfSysPropIsEmpty(TRUSTSTORE_PASSWORD_ARG, TRUSTSTORE_PASSWORD_PROPERTY_NAME, TRUSTSTORE_PASSWORD_FILE);
     SslContextFactory sslContextFactory = new SslContextFactory();
     sslContextFactory.setKeyStorePath(getKeyStoreLocation());
     sslContextFactory.setKeyStorePassword(getKeyStorePassword());
@@ -171,7 +191,7 @@ public class SSLUtil {
       char[] passwordChars = config.getPassword(propertyName);
       return (ArrayUtils.isNotEmpty(passwordChars)) ? new String(passwordChars) : null;
     } catch (Exception e) {
-      LOG.warn(String.format("Could not load password %s from credential store, using default password", propertyName));
+      LOG.warn(String.format("Could not load password %s from credential store, using default password", propertyName), e);
       return null;
     }
   }
@@ -193,7 +213,7 @@ public class SSLUtil {
   /**
    * Put private key into in-memory keystore and write it to a file (JKS file)
    */
-  public static void setKeyAndCertInKeystore(X509Certificate cert, KeyPair keyPair, KeyStore keyStore, String keyStoreLocation, char[] password)
+  private static void setKeyAndCertInKeystore(X509Certificate cert, KeyPair keyPair, KeyStore keyStore, String keyStoreLocation, char[] password)
     throws Exception {
     Certificate[] certChain = new Certificate[1];
     certChain[0] = cert;
@@ -201,7 +221,7 @@ public class SSLUtil {
       keyStore.setKeyEntry("logsearch.alias", keyPair.getPrivate(), password, certChain);
       keyStore.store(fos, password);
     } catch (Exception e) {
-      LOG.error("Could not write certificate to Keystore");
+      LOG.error("Could not write certificate to Keystore", e);
       throw e;
     }
   }
@@ -209,7 +229,7 @@ public class SSLUtil {
   /**
    * Create in-memory keypair with bouncy castle
    */
-  public static KeyPair createKeyPair(String encryptionType, int byteCount)
+  private static KeyPair createKeyPair(String encryptionType, int byteCount)
     throws NoSuchProviderException, NoSuchAlgorithmException {
     Security.addProvider(new BouncyCastleProvider());
     KeyPairGenerator keyPairGenerator = createKeyPairGenerator(encryptionType, byteCount);
@@ -219,7 +239,7 @@ public class SSLUtil {
   /**
    * Generate X509 certificate if it does not exist
    */
-  public static X509Certificate generateCertificate(String certificateLocation, KeyPair keyPair, String algorithm) throws Exception {
+  private static X509Certificate generateCertificate(String certificateLocation, KeyPair keyPair, String algorithm) throws Exception {
     try {
       File certFile = new File(certificateLocation);
       if (certFile.exists()) {
@@ -227,44 +247,65 @@ public class SSLUtil {
         return getCertFile(certificateLocation);
       } else {
         Security.addProvider(new BouncyCastleProvider());
-        X509Certificate cert = SSLUtil.createCert(keyPair, algorithm, InetAddress.getLocalHost().getCanonicalHostName());
+        X509Certificate cert = createCert(keyPair, algorithm, InetAddress.getLocalHost().getCanonicalHostName());
         FileUtils.writeByteArrayToFile(certFile, cert.getEncoded());
         return cert;
       }
     } catch (Exception e) {
-      LOG.error("Could not create certificate.");
+      LOG.error("Could not create certificate.", e);
       throw e;
     }
   }
 
-  private static void setPasswordIfSysPropIsEmpty(String pwdArg, String propertyName, String fileName) {
-    if (StringUtils.isEmpty(System.getProperty(pwdArg))) {
+  private static void ensureStorePassword(String locationArg, String pwdArg, String propertyName, String fileName) {
+    if (StringUtils.isNotEmpty(System.getProperty(locationArg)) && StringUtils.isEmpty(System.getProperty(pwdArg))) {
       String password = getPassword(propertyName, fileName);
       System.setProperty(pwdArg, password);
     }
   }
+  
+  public static void ensureStorePasswords() {
+    ensureStorePassword(KEYSTORE_LOCATION_ARG, KEYSTORE_PASSWORD_ARG, KEYSTORE_PASSWORD_PROPERTY_NAME, KEYSTORE_PASSWORD_FILE);
+    ensureStorePassword(TRUSTSTORE_LOCATION_ARG, TRUSTSTORE_PASSWORD_ARG, TRUSTSTORE_PASSWORD_PROPERTY_NAME, TRUSTSTORE_PASSWORD_FILE);
+  }
 
   private static X509Certificate getCertFile(String location) throws Exception {
     try (FileInputStream fos = new FileInputStream(location)) {
       CertificateFactory factory = CertificateFactory.getInstance("X.509");
       return (X509Certificate) factory.generateCertificate(fos);
     } catch (Exception e) {
-      LOG.error("Cannot read cert file. ('{}')", location);
+      LOG.error("Cannot read cert file. ('" + location + "')", e);
       throw e;
     }
   }
 
   private static X509Certificate createCert(KeyPair keyPair, String signatureAlgoritm, String domainName)
-    throws CertificateEncodingException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
-    X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator();
-    v3CertGen.setSerialNumber(BigInteger.valueOf(Math.abs(new SecureRandom().nextInt())));
-    v3CertGen.setIssuerDN(new X509Principal("CN=" + domainName + ", OU=None, O=None L=None, C=None"));
-    v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30));
-    v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365*10)));
-    v3CertGen.setSubjectDN(new X509Principal("CN=" + domainName + ", OU=None, O=None L=None, C=None"));
-    v3CertGen.setPublicKey(keyPair.getPublic());
-    v3CertGen.setSignatureAlgorithm(signatureAlgoritm);
-    return v3CertGen.generate(keyPair.getPrivate());
+    throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, OperatorCreationException, CertificateException, IOException {
+    
+    RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
+    RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
+    
+    AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find(signatureAlgoritm);
+    AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
+    BcContentSignerBuilder sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId);
+    
+    SubjectPublicKeyInfo pubKey = new SubjectPublicKeyInfo(sigAlgId, rsaPublicKey.getEncoded());
+    
+    X509v3CertificateBuilder v3CertBuilder = new X509v3CertificateBuilder(
+        new X500Name("CN=" + domainName + ", OU=None, O=None L=None, C=None"),
+        BigInteger.valueOf(Math.abs(new SecureRandom().nextInt())),
+        new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30),
+        new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365*10)),
+        new X500Name("CN=" + domainName + ", OU=None, O=None L=None, C=None"),
+        pubKey);
+    
+    RSAKeyParameters keyParams = new RSAKeyParameters(true, rsaPrivateKey.getPrivateExponent(), rsaPrivateKey.getModulus());
+    ContentSigner contentSigner = sigGen.build(keyParams);
+    
+    X509CertificateHolder certificateHolder = v3CertBuilder.build(contentSigner);
+    
+    JcaX509CertificateConverter certConverter = new JcaX509CertificateConverter();
+    return certConverter.getCertificate(certificateHolder);
   }
 
   private static KeyPairGenerator createKeyPairGenerator(String algorithmIdentifier, int bitCount)
@@ -274,4 +315,46 @@ public class SSLUtil {
     return kpg;
   }
 
+  /**
+   * Create keystore with keys and certificate (only if the keystore does not exist or if you have no permissions on the keystore file)
+   */
+  public static void loadKeystore() {
+    try {
+      String certFolder = PropertiesHelper.getProperty(LOGSEARCH_CERT_FOLDER_LOCATION, LOGSEARCH_CERT_DEFAULT_FOLDER);
+      String certAlgorithm = PropertiesHelper.getProperty(LOGSEARCH_CERT_ALGORITHM, LOGSEARCH_CERT_DEFAULT_ALGORITHM);
+      String certLocation = String.format("%s/%s", LOGSEARCH_CERT_DEFAULT_FOLDER, LOGSEARCH_CERT_FILENAME);
+      String keyStoreLocation = StringUtils.isNotEmpty(getKeyStoreLocation()) ? getKeyStoreLocation()
+        : String.format("%s/%s", LOGSEARCH_CERT_DEFAULT_FOLDER, LOGSEARCH_KEYSTORE_FILENAME);
+      char[] password = StringUtils.isNotEmpty(getKeyStorePassword()) ?
+        getKeyStorePassword().toCharArray() : LOGSEARCH_KEYSTORE_DEFAULT_PASSWORD.toCharArray();
+      boolean keyStoreFileExists = new File(keyStoreLocation).exists();
+      if (!keyStoreFileExists) {
+        FileUtil.createDirectory(certFolder);
+        LOG.warn("Keystore file ('{}') does not exist, creating new one. " +
+          "If the file exists, make sure you have proper permissions on that.", keyStoreLocation);
+        if (isKeyStoreSpecified() && !"JKS".equalsIgnoreCase(getKeyStoreType())) {
+          throw new RuntimeException(String.format("Keystore does not exist. Only JKS keystore can be auto generated. (%s)", keyStoreLocation));
+        }
+        LOG.info("SSL keystore is not specified. Generating it with certificate ... (using default format: JKS)");
+        Security.addProvider(new BouncyCastleProvider());
+        KeyPair keyPair = createKeyPair("RSA", 2048);
+        File privateKeyFile = new File(String.format("%s/%s", certFolder, LOGSEARCH_KEYSTORE_PRIVATE_KEY));
+        if (!privateKeyFile.exists()) {
+          FileUtils.writeByteArrayToFile(privateKeyFile, keyPair.getPrivate().getEncoded());
+        }
+        File file = new File(String.format("%s/%s", certFolder, LOGSEARCH_KEYSTORE_PUBLIC_KEY));
+        if (!file.exists()) {
+          FileUtils.writeByteArrayToFile(file, keyPair.getPublic().getEncoded());
+        }
+        X509Certificate cert = generateCertificate(certLocation, keyPair, certAlgorithm);
+        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+        keyStore.load(null, password);
+        setKeyAndCertInKeystore(cert, keyPair, keyStore, keyStoreLocation, password);
+        FileUtil.setPermissionOnDirectory(certFolder, "600");
+      }
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+
 }