Last active
July 5, 2020 11:52
-
-
Save bbottema/d2fa007221956e684707e1db45ac1afb to your computer and use it in GitHub Desktop.
Utility code for creating SSLSocketFactory for sending email
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
KeyStoreInfo optionalKeyStoreInfo = new KeyStoreInfo(keyStorePath, password, type); // without type param defaults to "JKS" | |
KeyStoreInfo trustKeyStoreInfo = new KeyStoreInfo(keyStorePath, password, type); | |
SSLSocketFactory yourSSLSocketFactory = new SSLConfiguration(optionalKeyStoreInfo, trustKeyStoreInfo).getSSLSocketFactory(); | |
Session session = mailer.getSession(); | |
session.getProperties().put("mail.smtp.ssl.socketFactory", yourSSLSocketFactory); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.simplejavamail.sslhelper; | |
import org.simplejavamail.internal.util.MiscUtil; | |
@SuppressWarnings("SameParameterValue") | |
public class KeyStoreInfo { | |
private final String keyStorePath; | |
private final String password; | |
private final String type /*= "JKS"*/; | |
/** | |
* Delegates to {@link #KeyStoreInfo(String, String, String)} using "JKS" as type. | |
*/ | |
public KeyStoreInfo(final String keyStorePath, final String password) { | |
this(keyStorePath, password, "JKS"); | |
} | |
public KeyStoreInfo(final String keyStorePath, final String password, final String type) { | |
this.keyStorePath = MiscUtil.checkNotNull(keyStorePath, "Argument [keyStorePath] may not be null"); | |
this.password = MiscUtil.checkNotNull(password, "Argument [password] may not be null"); | |
this.type = MiscUtil.checkNotNull(type, "Argument [type] may not be null"); | |
} | |
public String getKeyStorePath() { | |
return keyStorePath; | |
} | |
public String getPassword() { | |
return password; | |
} | |
public String getType() { | |
return type; | |
} | |
@Override | |
public String toString() { | |
return "[KEY STORE] PATH:" + keyStorePath + " PASSWORD:xxx" + " TYPE:" + type; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.simplejavamail.sslhelper; | |
import org.simplejavamail.internal.util.MiscUtil; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import javax.net.ssl.KeyManagerFactory; | |
import javax.net.ssl.SSLContext; | |
import javax.net.ssl.SSLSocketFactory; | |
import javax.net.ssl.TrustManagerFactory; | |
import java.io.FileInputStream; | |
import java.io.FileNotFoundException; | |
import java.io.IOException; | |
import java.security.KeyManagementException; | |
import java.security.KeyStore; | |
import java.security.KeyStoreException; | |
import java.security.NoSuchAlgorithmException; | |
import java.security.UnrecoverableKeyException; | |
import java.security.cert.CertificateException; | |
public class SSLSocketFactoryFactory { | |
private static final Logger LOGGER = LoggerFactory.getLogger(SSLConfiguration.class); | |
private final KeyStoreInfo keyStoreInfo; | |
private final KeyStoreInfo trustKeyStoreInfo; | |
@SuppressWarnings("SameParameterValue") | |
private SSLConfiguration(final KeyStoreInfo keyStoreInfo, final KeyStoreInfo trustKeyStoreInfo) { | |
this.keyStoreInfo = keyStoreInfo; | |
this.trustKeyStoreInfo = trustKeyStoreInfo; | |
} | |
public SSLSocketFactory getSSLSocketFactory() { | |
MiscUtil.checkNotNull(trustKeyStoreInfo, "trustKeyStoreInfo may not be null"); | |
FileInputStream s1 = null; | |
FileInputStream s2 = null; | |
try { | |
final SSLContext context = SSLContext.getInstance("SSL"); | |
final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509"); | |
final KeyStore trustKeyStore = KeyStore.getInstance(trustKeyStoreInfo.getType()); | |
trustKeyStore.load(s1 = new FileInputStream(trustKeyStoreInfo.getKeyStorePath()), trustKeyStoreInfo.getPassword().toCharArray()); | |
trustManagerFactory.init(trustKeyStore); | |
KeyStore keyStore = null; | |
if (keyStoreInfo != null && keyStoreInfo.getKeyStorePath() != null) { | |
final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); | |
keyStore = KeyStore.getInstance(keyStoreInfo.getType()); | |
keyStore.load(s2 = new FileInputStream(keyStoreInfo.getKeyStorePath()), keyStoreInfo.getPassword().toCharArray()); | |
keyManagerFactory.init(keyStore, keyStoreInfo.getPassword().toCharArray()); | |
context.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); | |
} else { | |
context.init(null, trustManagerFactory.getTrustManagers(), null); | |
} | |
if (keyStore != null) { | |
LOGGER.info("SSL: Key store:{}", keyStoreInfo.getKeyStorePath()); | |
} | |
LOGGER.info("SSL: Trust key store:{}", trustKeyStoreInfo.getKeyStorePath()); | |
return context.getSocketFactory(); | |
} catch (IOException | KeyManagementException | KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException e) { | |
throw new RuntimeException(e.getMessage(), e); | |
} finally { | |
tryCloseStream(s1); | |
tryCloseStream(s2); | |
} | |
} | |
private static void tryCloseStream(final FileInputStream s1) { | |
if (s1 != null) { | |
try { | |
s1.close(); | |
} catch (final IOException e) { | |
LOGGER.error("unable to close stream", e); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment