getTags();
public Object putPassword(String tag, String password);
public void commit() throws IOException, ClassCastException,
NullPointerException;
}
tomcatjss-8.4.0/core/src/main/java/org/apache/tomcat/util/net/jss/PlainPasswordFile.java 0000664 0000000 0000000 00000012740 14420205342 0031210 0 ustar 00root root 0000000 0000000 /* BEGIN COPYRIGHT BLOCK
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Copyright (C) 2007 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK */
package org.apache.tomcat.util.net.jss;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Enumeration;
import java.util.Properties;
public class PlainPasswordFile implements IPasswordStore {
private String mPwdPath = "";
private Properties mPwdStore;
private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(PlainPasswordFile.class);
public PlainPasswordFile() {
mPwdStore = new Properties();
}
/**
* Initialization method to read passwords(key and element pairs) from a file.
*
* Every property occupies one line of the input stream. Each line is terminated by a line terminator (
* \n
or \r
or \r\n
). Lines are processed until end of
* file is reached.
*
* A line that contains only whitespace or whose first non-whitespace character is an ASCII #
* is ignored (thus, #
indicates comment line).
*
* Every line other than a blank line or a comment line describes one property to be added to the table.
* The characters before the delimiter =
forms the key
and the characters after
* the =
is assigned as value
to the key.
*
* As an example, each of the following lines specify the key "Truth"
and the associated element
* value "Beauty"
:
*
*
*
* Truth = Beauty
* Truth= Beauty
* Truth =Beauty
*
*
*
* Note that the space appearing before/after =
is ignored. However, the space appearing in between are
* stored.
*
* Example:
*
*
* Welcome Message = Hello World
*
*
* assigns value Hello World
to key Welcome Message
*
*
* If the line doesn't have the delimiter =
, the method throws an IOException
*
* @param pwdPath the input file path.
* @exception IOException if an error occurred when reading from the
* input stream.
*/
@Override
public void init(String pwdPath) throws IOException {
logger.debug("PlainPasswordFile: Initializing PlainPasswordFile");
// initialize mPwdStore
mPwdPath = pwdPath;
try (FileInputStream file = new FileInputStream(mPwdPath);
InputStreamReader isr = new InputStreamReader(file);
BufferedReader br = new BufferedReader(isr)) {
String line;
int index = 1;
while ((line = br.readLine()) != null) {
// Remove any leading or trailing spaces
line = line.trim();
if (line.startsWith("#") || line.isEmpty())
continue;
String[] parts = line.split("=", 2);
if (parts.length < 2) {
throw new IOException("Missing delimiter '=' in file " + mPwdPath + " in line " + index);
}
// Load key value into the password store
mPwdStore.put(parts[0].trim(), parts[1].trim());
index++;
}
}
}
@Override
public String getPassword(String tag) {
return getPassword(tag, 0);
}
@Override
public String getPassword(String tag, int iteration) {
return mPwdStore.getProperty(tag);
}
// return an array of String-based tag
@Override
@SuppressWarnings("unchecked")
public Enumeration getTags() {
return (Enumeration) mPwdStore.propertyNames();
}
@Override
public Object putPassword(String tag, String password) {
return mPwdStore.setProperty(tag, password);
}
@Override
public synchronized void commit()
throws IOException, ClassCastException, NullPointerException {
try (FileOutputStream file = new FileOutputStream(mPwdPath);
OutputStreamWriter osw = new OutputStreamWriter(file);
BufferedWriter bw = new BufferedWriter(osw)) {
for (Enumeration> e = mPwdStore.keys(); e.hasMoreElements();) {
String key = ((String) e.nextElement()).trim();
String val = ((String) mPwdStore.get(key)).trim();
bw.write(key + "=" + val);
bw.newLine();
}
}
}
public int getSize() {
return mPwdStore.size();
}
}
tomcatjss-8.4.0/core/src/main/java/org/apache/tomcat/util/net/jss/TomcatJSS.java 0000664 0000000 0000000 00000050343 14420205342 0027432 0 ustar 00root root 0000000 0000000 /* BEGIN COPYRIGHT BLOCK
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Copyright (C) 2017 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK */
package org.apache.tomcat.util.net.jss;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Properties;
import javax.naming.ConfigurationException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.lang3.StringUtils;
import org.mozilla.jss.CertDatabaseException;
import org.mozilla.jss.CryptoManager;
import org.mozilla.jss.InitializationValues;
import org.mozilla.jss.KeyDatabaseException;
import org.mozilla.jss.NoSuchTokenException;
import org.mozilla.jss.NotInitializedException;
import org.mozilla.jss.crypto.AlreadyInitializedException;
import org.mozilla.jss.crypto.CryptoToken;
import org.mozilla.jss.crypto.TokenException;
import org.mozilla.jss.ssl.SSLAlertEvent;
import org.mozilla.jss.ssl.SSLHandshakeCompletedEvent;
import org.mozilla.jss.ssl.SSLServerSocket;
import org.mozilla.jss.ssl.SSLSocketListener;
import org.mozilla.jss.util.IncorrectPasswordException;
import org.mozilla.jss.util.Password;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
public class TomcatJSS implements SSLSocketListener {
public static final Logger logger = LoggerFactory.getLogger(TomcatJSS.class);
public static final TomcatJSS INSTANCE = new TomcatJSS();
public static final int MAX_LOGIN_ATTEMPTS = 3;
public static final String CATALINA_BASE = "catalina.base";
public static TomcatJSS getInstance() { return INSTANCE; }
Collection socketListeners = new ArrayList<>();
String certdbDir;
CryptoManager manager;
String passwordClass;
String passwordFile;
IPasswordStore passwordStore;
String serverCertNickFile;
String serverCertNick;
String clientAuth = "want";
boolean requireClientAuth;
boolean wantClientAuth;
boolean enableOCSP;
String ocspResponderURL;
String ocspResponderCertNickname;
int ocspCacheSize = 1000; // entries
int ocspMinCacheEntryDuration = 3600; // seconds (default: 1 hour)
int ocspMaxCacheEntryDuration = 86400; // seconds (default: 24 hours)
int ocspTimeout = 60; // seconds (default: 1 minute)
String strictCiphers;
boolean boolStrictCiphers;
String sslRangeCiphers;
String sslOptions;
String ssl2Ciphers;
String ssl3Ciphers;
String tlsCiphers;
boolean initialized;
public void addSocketListener(SSLSocketListener listener) {
socketListeners.add(listener);
}
public void removeSocketListener(SSLSocketListener listener) {
socketListeners.remove(listener);
}
public Collection getSocketListeners() {
return socketListeners;
}
public String getCertdbDir() {
return certdbDir;
}
public void setCertdbDir(String certdbDir) {
this.certdbDir = certdbDir;
}
public String getPasswordClass() {
return passwordClass;
}
public void setPasswordClass(String passwordClass) {
this.passwordClass = passwordClass;
}
public String getPasswordFile() {
return passwordFile;
}
public void setPasswordFile(String passwordFile) {
this.passwordFile = passwordFile;
}
public String getServerCertNickFile() {
return serverCertNickFile;
}
public IPasswordStore getPasswordStore() {
return passwordStore;
}
public void setPasswordStore(IPasswordStore passwordStore) {
this.passwordStore = passwordStore;
}
public void setServerCertNickFile(String serverCertNickFile) {
this.serverCertNickFile = serverCertNickFile;
}
public String getServerCertNick() {
return serverCertNick;
}
public void setServerCertNick(String serverCertNick) {
this.serverCertNick = serverCertNick;
}
public String getClientAuth() {
return clientAuth;
}
public void setClientAuth(String clientAuth) {
this.clientAuth = clientAuth;
}
public boolean getRequireClientAuth() {
return requireClientAuth;
}
public boolean getWantClientAuth() {
return wantClientAuth;
}
public boolean getEnableOCSP() {
return enableOCSP;
}
public void setEnableOCSP(boolean enableOCSP) {
this.enableOCSP = enableOCSP;
}
public String getOcspResponderURL() {
return ocspResponderURL;
}
public void setOcspResponderURL(String ocspResponderURL) {
this.ocspResponderURL = ocspResponderURL;
}
public String getOcspResponderCertNickname() {
return ocspResponderCertNickname;
}
public void setOcspResponderCertNickname(String ocspResponderCertNickname) {
this.ocspResponderCertNickname = ocspResponderCertNickname;
}
public int getOcspCacheSize() {
return ocspCacheSize;
}
public void setOcspCacheSize(int ocspCacheSize) {
this.ocspCacheSize = ocspCacheSize;
}
public int getOcspMinCacheEntryDuration() {
return ocspMinCacheEntryDuration;
}
public void setOcspMinCacheEntryDuration(int ocspMinCacheEntryDuration) {
this.ocspMinCacheEntryDuration = ocspMinCacheEntryDuration;
}
public int getOcspMaxCacheEntryDuration() {
return ocspMaxCacheEntryDuration;
}
public void setOcspMaxCacheEntryDuration(int ocspMaxCacheEntryDuration) {
this.ocspMaxCacheEntryDuration = ocspMaxCacheEntryDuration;
}
public int getOcspTimeout() {
return ocspTimeout;
}
public void setOcspTimeout(int ocspTimeout) {
this.ocspTimeout = ocspTimeout;
}
public void loadJSSConfig(String jssConf) throws IOException {
File configFile = new File(jssConf);
loadJSSConfig(configFile);
}
public void loadJSSConfig(File configFile) throws IOException {
Properties config = new Properties();
try (FileReader fr = new FileReader(configFile)) {
config.load(fr);
loadJSSConfig(config);
}
}
public void loadJSSConfig(Properties config) {
String certdbDirProp = config.getProperty("certdbDir");
if (certdbDirProp != null)
setCertdbDir(certdbDirProp);
String passwordClassProp = config.getProperty("passwordClass");
if (passwordClassProp != null)
setPasswordClass(passwordClassProp);
String passwordFileProp = config.getProperty("passwordFile");
if (passwordFileProp != null)
setPasswordFile(passwordFileProp);
String enableOCSPProp = config.getProperty("enableOCSP");
if (enableOCSPProp != null)
setEnableOCSP(Boolean.parseBoolean(enableOCSPProp));
String ocspResponderURLProp = config.getProperty("ocspResponderURL");
if (ocspResponderURLProp != null)
setOcspResponderURL(ocspResponderURLProp);
String ocspResponderCertNicknameProp = config.getProperty("ocspResponderCertNickname");
if (ocspResponderCertNicknameProp != null)
setOcspResponderCertNickname(ocspResponderCertNicknameProp);
String ocspCacheSizeProp = config.getProperty("ocspCacheSize");
if (StringUtils.isNotEmpty(ocspCacheSizeProp))
setOcspCacheSize(Integer.parseInt(ocspCacheSizeProp));
String ocspMinCacheEntryDurationProp = config.getProperty("ocspMinCacheEntryDuration");
if (StringUtils.isNotEmpty(ocspMinCacheEntryDurationProp))
setOcspMinCacheEntryDuration(Integer.parseInt(ocspMinCacheEntryDurationProp));
String ocspMaxCacheEntryDurationProp = config.getProperty("ocspMaxCacheEntryDuration");
if (StringUtils.isNotEmpty(ocspMaxCacheEntryDurationProp))
setOcspMaxCacheEntryDuration(Integer.parseInt(ocspMaxCacheEntryDurationProp));
String ocspTimeoutProp = config.getProperty("ocspTimeout");
if (StringUtils.isNotEmpty(ocspTimeoutProp))
setOcspTimeout(Integer.parseInt(ocspTimeoutProp));
}
public void loadTomcatConfig(String serverXml)
throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
File configFile = new File(serverXml);
loadTomcatConfig(configFile);
}
public void loadTomcatConfig(File configFile)
throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(configFile);
loadTomcatConfig(document);
}
public void loadTomcatConfig(Document document) throws XPathExpressionException {
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
Element connector = (Element) xpath.evaluate(
"/Server/Service[@name='Catalina']/Connector[@SSLEnabled='true']",
document, XPathConstants.NODE);
String certDbProp = connector.getAttribute("certdbDir");
if (certDbProp != null)
setCertdbDir(certDbProp);
String passwordClassProp = connector.getAttribute("passwordClass");
if (passwordClassProp != null)
setPasswordClass(passwordClassProp);
String passwordFileProp = connector.getAttribute("passwordFile");
if (passwordFileProp != null)
setPasswordFile(passwordFileProp);
String serverCertNickFileProp = connector.getAttribute("serverCertNickFile");
if (serverCertNickFileProp != null)
setServerCertNickFile(serverCertNickFileProp);
String enableOCSPProp = connector.getAttribute("enableOCSP");
if (enableOCSPProp != null)
setEnableOCSP(Boolean.parseBoolean(enableOCSPProp));
String ocspResponderURLProp = connector.getAttribute("ocspResponderURL");
if (ocspResponderURLProp != null)
setOcspResponderURL(ocspResponderURLProp);
String ocspResponderCertNicknameProp = connector.getAttribute("ocspResponderCertNickname");
if (ocspResponderCertNicknameProp != null)
setOcspResponderCertNickname(ocspResponderCertNicknameProp);
String ocspCacheSizeProp = connector.getAttribute("ocspCacheSize");
if (StringUtils.isNotEmpty(ocspCacheSizeProp))
setOcspCacheSize(Integer.parseInt(ocspCacheSizeProp));
String ocspMinCacheEntryDurationProp = connector.getAttribute("ocspMinCacheEntryDuration");
if (StringUtils.isNotEmpty(ocspMinCacheEntryDurationProp))
setOcspMinCacheEntryDuration(Integer.parseInt(ocspMinCacheEntryDurationProp));
String ocspMaxCacheEntryDurationProp = connector.getAttribute("ocspMaxCacheEntryDuration");
if (StringUtils.isNotEmpty(ocspMaxCacheEntryDurationProp))
setOcspMaxCacheEntryDuration(Integer.parseInt(ocspMaxCacheEntryDurationProp));
String ocspTimeoutProp = connector.getAttribute("ocspTimeout");
if (StringUtils.isNotEmpty(ocspTimeoutProp))
setOcspTimeout(Integer.parseInt(ocspTimeoutProp));
}
/**
* Load configuration from jss.conf (if available) or server.xml.
* @throws IOException
* @throws SAXException
* @throws ParserConfigurationException
* @throws XPathExpressionException
*/
public void loadConfig() throws IOException, XPathExpressionException, ParserConfigurationException, SAXException {
String catalinaBase = System.getProperty(CATALINA_BASE);
String jssConf = catalinaBase + "/conf/jss.conf";
File configFile = new File(jssConf);
if (configFile.exists()) {
logger.info("TomcatJSS: Loading JSS configuration from {}", jssConf);
loadJSSConfig(configFile);
} else {
String serverXml = catalinaBase + "/conf/server.xml";
logger.info("TomcatJSS: Loading JSS configuration from {}", serverXml);
loadTomcatConfig(serverXml);
}
}
public void init() throws KeyDatabaseException, CertDatabaseException, GeneralSecurityException,
NotInitializedException, InstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException, IOException,
NoSuchTokenException, TokenException, ConfigurationException {
if (initialized) {
return;
}
logger.info("TomcatJSS: initialization");
if (certdbDir == null) {
certdbDir = System.getProperty(CATALINA_BASE) + File.separator + "alias";
}
logger.debug("TomcatJSS: certdbDir: {}", certdbDir);
if (passwordClass == null) {
passwordClass = PlainPasswordFile.class.getName();
}
logger.debug("TomcatJSS: passwordClass: {}", passwordClass);
if (passwordFile == null) {
passwordFile = System.getProperty(CATALINA_BASE) + File.separator +
"conf" + File.separator + "password.conf";
}
logger.debug("TomcatJSS: passwordFile: {}", passwordFile);
if (StringUtils.isNotEmpty(serverCertNickFile)) {
logger.debug("TomcatJSS: serverCertNickFile: {}", serverCertNickFile);
}
InitializationValues vals = new InitializationValues(certdbDir);
vals.removeSunProvider = false;
vals.installJSSProvider = true;
try {
CryptoManager.initialize(vals);
} catch (AlreadyInitializedException e) {
logger.warn("TomcatJSS: {}", e, e);
}
manager = CryptoManager.getInstance();
passwordStore = (IPasswordStore) Class.forName(passwordClass).getDeclaredConstructor().newInstance();
passwordStore.init(passwordFile);
login();
if (StringUtils.isNotEmpty(serverCertNickFile)) {
serverCertNick = new String(Files.readAllBytes(Paths.get(serverCertNickFile))).trim();
logger.debug("serverCertNick: {}", serverCertNick);
}
logger.debug("clientAuth: {}", clientAuth);
if (clientAuth.equalsIgnoreCase("true")) {
requireClientAuth = true;
} else if (clientAuth.equalsIgnoreCase("yes")) {
requireClientAuth = true;
logger.warn("The \"yes\" value for clientAuth has been deprecated. Use \"true\" instead.");
} else if (clientAuth.equalsIgnoreCase("want")) {
wantClientAuth = true;
}
logger.debug("requireClientAuth: {}", requireClientAuth);
logger.debug("wantClientAuth: {}", wantClientAuth);
if (requireClientAuth || wantClientAuth) {
configureOCSP();
}
// 12 hours = 43200 seconds
SSLServerSocket.configServerSessionIDCache(0, 43200, 43200, null);
logger.info("TomcatJSS: initialization complete");
initialized = true;
}
public void login() throws NoSuchTokenException, TokenException {
logger.debug("TomcatJSS: logging into tokens");
Enumeration tags = passwordStore.getTags();
while (tags.hasMoreElements()) {
String tag = tags.nextElement();
if (!tag.equals("internal") && !tag.startsWith("hardware-")) {
continue;
}
login(tag);
}
}
public void login(String tag) throws NoSuchTokenException, TokenException {
CryptoToken token = getToken(tag);
if (token.isLoggedIn()) {
logger.debug("TomcatJSS: already logged into {}", tag);
return;
}
logger.debug("TomcatJSS: logging into {}", tag);
int iteration = 0;
do {
String strPassword = passwordStore.getPassword(tag, iteration);
if (strPassword == null) {
logger.debug("TomcatJSS: no password for {}", tag);
return;
}
Password password = new Password(strPassword.toCharArray());
try {
token.login(password);
return; //NOSONAR - Not a redundant return, break will print the final error message even on success.
} catch (IncorrectPasswordException e) {
logger.warn("TomcatJSS: incorrect password");
iteration ++;
} finally {
password.clear();
}
} while (iteration < MAX_LOGIN_ATTEMPTS);
logger.error("TomcatJSS: failed to log into {}", tag);
}
public CryptoToken getToken(String tag) throws NoSuchTokenException {
if (tag.equals("internal")) {
return manager.getInternalKeyStorageToken();
}
if (tag.startsWith("hardware-")) {
String tokenName = tag.substring(9);
return manager.getTokenByName(tokenName);
}
// non-token password entry
return null;
}
public void configureOCSP() throws GeneralSecurityException, ConfigurationException {
logger.info("configuring OCSP");
logger.debug("enableOCSP: {}", enableOCSP);
if (!enableOCSP) {
return;
}
logger.debug("ocspResponderURL: {}", ocspResponderURL);
if (StringUtils.isEmpty(ocspResponderURL)) {
ocspResponderURL = null;
}
logger.debug("ocspResponderCertNickname: {}", ocspResponderCertNickname);
if (StringUtils.isEmpty(ocspResponderCertNickname)) {
ocspResponderCertNickname = null;
}
// Check to see if the ocsp url and nickname are both set or not set
if (ocspResponderURL == null && ocspResponderCertNickname != null) {
throw new ConfigurationException("Missing OCSP responder URL");
}
if (ocspResponderURL != null && ocspResponderCertNickname == null) {
throw new ConfigurationException("Missing OCSP responder certificate nickname");
}
manager.configureOCSP(
true,
ocspResponderURL,
ocspResponderCertNickname);
logger.debug("ocspCacheSize: {}", ocspCacheSize);
logger.debug("ocspMinCacheEntryDuration: {}", ocspMinCacheEntryDuration);
logger.debug("ocspMaxCacheEntryDuration: {}", ocspMaxCacheEntryDuration);
manager.OCSPCacheSettings(ocspCacheSize,
ocspMinCacheEntryDuration,
ocspMaxCacheEntryDuration);
logger.debug("ocspTimeout: {}", ocspTimeout);
manager.setOCSPTimeout(ocspTimeout);
}
@Override
public void alertReceived(SSLAlertEvent event) {
for (SSLSocketListener listener : socketListeners) {
listener.alertReceived(event);
}
}
@Override
public void alertSent(SSLAlertEvent event) {
for (SSLSocketListener listener : socketListeners) {
listener.alertSent(event);
}
}
@Override
public void handshakeCompleted(SSLHandshakeCompletedEvent event) {
for (SSLSocketListener listener : socketListeners) {
listener.handshakeCompleted(event);
}
}
}
tomcatjss-8.4.0/core/src/main/java/org/dogtagpki/ 0000775 0000000 0000000 00000000000 14420205342 0021652 5 ustar 00root root 0000000 0000000 tomcatjss-8.4.0/core/src/main/java/org/dogtagpki/tomcat/ 0000775 0000000 0000000 00000000000 14420205342 0023141 5 ustar 00root root 0000000 0000000 tomcatjss-8.4.0/core/src/main/java/org/dogtagpki/tomcat/Http11NioProtocol.java 0000664 0000000 0000000 00000007030 14420205342 0027255 0 ustar 00root root 0000000 0000000 package org.dogtagpki.tomcat;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.tomcat.util.net.jss.TomcatJSS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Http11NioProtocol extends org.apache.coyote.http11.Http11NioProtocol {
public static Logger logger = LoggerFactory.getLogger(Http11NioProtocol.class);
TomcatJSS tomcatjss = TomcatJSS.getInstance();
public String getCertdbDir() {
return tomcatjss.getCertdbDir();
}
public void setCertdbDir(String certdbDir) {
tomcatjss.setCertdbDir(certdbDir);
}
public String getPasswordClass() {
return tomcatjss.getPasswordClass();
}
public void setPasswordClass(String passwordClass) {
tomcatjss.setPasswordClass(passwordClass);
}
public String getPasswordFile() {
return tomcatjss.getPasswordFile();
}
public void setPasswordFile(String passwordFile) {
tomcatjss.setPasswordFile(passwordFile);
}
public String getServerCertNickFile() {
return tomcatjss.getServerCertNickFile();
}
public void setServerCertNickFile(String serverCertNickFile) {
tomcatjss.setServerCertNickFile(serverCertNickFile);
}
public boolean getEnabledOCSP() {
return tomcatjss.getEnableOCSP();
}
public void setEnableOCSP(boolean enableOCSP) {
tomcatjss.setEnableOCSP(enableOCSP);
}
public String getOcspResponderURL() {
return tomcatjss.getOcspResponderURL();
}
public void setOcspResponderURL(String ocspResponderURL) {
tomcatjss.setOcspResponderURL(ocspResponderURL);
}
public String getOcspResponderCertNickname() {
return tomcatjss.getOcspResponderCertNickname();
}
public void setOcspResponderCertNickname(String ocspResponderCertNickname) {
tomcatjss.setOcspResponderCertNickname(ocspResponderCertNickname);
}
public int getOcspCacheSize() {
return tomcatjss.getOcspCacheSize();
}
public void setOcspCacheSize(int ocspCacheSize) {
tomcatjss.setOcspCacheSize(ocspCacheSize);
}
public int getOcspMinCacheEntryDuration() {
return tomcatjss.getOcspMinCacheEntryDuration();
}
public void setOcspMinCacheEntryDuration(int ocspMinCacheEntryDuration) {
tomcatjss.setOcspMinCacheEntryDuration(ocspMinCacheEntryDuration);
}
public int getOcspMaxCacheEntryDuration() {
return tomcatjss.getOcspMaxCacheEntryDuration();
}
public void setOcspMaxCacheEntryDuration(int ocspMaxCacheEntryDuration) {
tomcatjss.setOcspMaxCacheEntryDuration(ocspMaxCacheEntryDuration);
}
public int getOcspTimeout() {
return tomcatjss.getOcspTimeout();
}
public void setOcspTimeout(int ocspTimeout) {
tomcatjss.setOcspTimeout(ocspTimeout);
}
public void setKeystorePassFile(String keystorePassFile) {
try {
Path path = Paths.get(keystorePassFile);
String password = new String(Files.readAllBytes(path)).trim();
setKeystorePass(password);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void setTruststorePassFile(String truststorePassFile) {
try {
Path path = Paths.get(truststorePassFile);
String password = new String(Files.readAllBytes(path)).trim();
setTruststorePass(password);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
tomcatjss-8.4.0/core/src/main/java/org/dogtagpki/tomcat/JSSListener.java 0000664 0000000 0000000 00000003670 14420205342 0026157 0 ustar 00root root 0000000 0000000 /* BEGIN COPYRIGHT BLOCK
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Copyright (C) 2019 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK */
package org.dogtagpki.tomcat;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
import org.apache.tomcat.util.net.jss.TomcatJSS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JSSListener implements LifecycleListener {
final static Logger logger = LoggerFactory.getLogger(JSSListener.class);
public String configFile;
public String getConfigFile() {
return configFile;
}
public void setConfigFile(String configFile) {
this.configFile = configFile;
}
@Override
public void lifecycleEvent(LifecycleEvent event) {
String type = event.getType();
if (type.equals(Lifecycle.BEFORE_INIT_EVENT)) {
initJSS();
}
}
public void initJSS() {
logger.info("JSSListener: Initializing JSS");
try {
TomcatJSS tomcatjss = TomcatJSS.getInstance();
tomcatjss.loadConfig();
tomcatjss.init();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
tomcatjss-8.4.0/docs/ 0000775 0000000 0000000 00000000000 14420205342 0014456 5 ustar 00root root 0000000 0000000 tomcatjss-8.4.0/docs/changes/ 0000775 0000000 0000000 00000000000 14420205342 0016066 5 ustar 00root root 0000000 0000000 tomcatjss-8.4.0/docs/changes/v8.1.0/ 0000775 0000000 0000000 00000000000 14420205342 0016720 5 ustar 00root root 0000000 0000000 tomcatjss-8.4.0/docs/changes/v8.1.0/Development-Changes.adoc 0000664 0000000 0000000 00000000375 14420205342 0023405 0 ustar 00root root 0000000 0000000 = Development Changes =
== Build Changes ==
By default the `./build.sh` will only create the JAR file instead of the RPM package.
The JAR file can be installed on the system using `./build.sh install`.
To build the RPM package, run `./build.sh rpm`.
tomcatjss-8.4.0/docs/changes/v8.1.0/Packaging-Changes.adoc 0000664 0000000 0000000 00000000347 14420205342 0023006 0 ustar 00root root 0000000 0000000 = Packaging Changes =
== Java Dependency Changes ==
TomcatJSS will now require OpenJDK 17.
== Java Archive Changes ==
The `/usr/share/java/tomcatjss-.jar` has been removed.
Use `/usr/share/java/tomcatjss.jar` instead.
tomcatjss-8.4.0/docs/development/ 0000775 0000000 0000000 00000000000 14420205342 0017000 5 ustar 00root root 0000000 0000000 tomcatjss-8.4.0/docs/development/Synchronizing-GitLab-Branch.adoc 0000664 0000000 0000000 00000003366 14420205342 0025037 0 ustar 00root root 0000000 0000000 = Synchronizing GitLab Branch =
== Overview ==
This page describes the procedure to synchronize a branch from an upstream repository
to a GitLab repository.
== Creating Access Token ==
In the GitLab repository create a project access token with a **write_repository** permission.
See link:https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html#creating-a-project-access-token[Creating a project access token].
== Configuring Synchronization ==
In the GitLab repository create the following variables:
* `UPSTREAM_URL`: The URL of the upstream repository.
** Unselect **Protect variable** to synchronize unprotected branches.
* `ACCESS_TOKEN`: The value of the access token.
** Unselect **Protect variable** to synchronize unprotected branches.
** Select **Mask variable** to keep the access token hidden.
See link:https://docs.gitlab.com/ee/ci/variables/#add-a-cicd-variable-to-a-project[Add a CI/CD variable to a project].
== Running Synchronization Manually ==
In the GitLab repository run a pipeline with the following parameters:
* **Run for branch name or tag**: The branch to be synchronized.
* **Variables**:
** `SYNC`: `true`
See link:https://docs.gitlab.com/ee/ci/pipelines/#run-a-pipeline-manually[Run a pipeline manually].
== Scheduling Automatic Synchronization ==
In the GitLab repository create a schedule with the following parameters:
* **Interval Pattern**: The frequency of synchronization.
** To synchronize every hour, enter: `0 * * * *`
* **Target Branch**: The branch to be synchronized.
* **Variables**:
** `SYNC`: `true`
Additional schedules can be created for synchronizing other branches.
See link:https://docs.gitlab.com/ee/ci/pipelines/schedules.html#configuring-pipeline-schedules[Configuring pipeline schedules].
tomcatjss-8.4.0/main/ 0000775 0000000 0000000 00000000000 14420205342 0014452 5 ustar 00root root 0000000 0000000 tomcatjss-8.4.0/main/pom.xml 0000664 0000000 0000000 00000006154 14420205342 0015775 0 ustar 00root root 0000000 0000000
4.0.0
org.dogtagpki.tomcatjss
tomcatjss-parent
${revision}
tomcatjss-main
jar
${project.groupId}
tomcatjss-core
${project.version}
${project.groupId}
tomcatjss-tomcat-9.0
${project.version}
org.apache.maven.plugins
maven-shade-plugin
1.2.2
package
shade
org.slf4j:slf4j-api
org.slf4j:slf4j-jdk14
org.apache.commons:commons-lang3
org.apache.tomcat:tomcat-catalina
org.apache.tomcat:tomcat-servlet-api
org.apache.tomcat:tomcat-jsp-api
org.apache.tomcat:tomcat-el-api
org.apache.tomcat:tomcat-juli
org.apache.tomcat:tomcat-annotations-api
org.apache.tomcat:tomcat-api
org.apache.tomcat:tomcat-jni
org.apache.tomcat:tomcat-coyote
org.apache.tomcat:tomcat-util
org.apache.tomcat:tomcat-util-scan
org.apache.tomcat:tomcat-jaspic-api
org.dogtagpki.jss:jss-base
tomcatjss-8.4.0/pom.xml 0000664 0000000 0000000 00000004074 14420205342 0015050 0 ustar 00root root 0000000 0000000
4.0.0
org.dogtagpki.tomcatjss
tomcatjss-parent
${revision}
pom
8.4.0-SNAPSHOT
UTF-8
core
tomcat-9.0
main
org.codehaus.mojo
flatten-maven-plugin
1.1.0
true
resolveCiFriendliesOnly
flatten
process-resources
flatten
flatten.clean
clean
clean
github
https://maven.pkg.github.com/OWNER/*
true
github
GitHub Packages
https://maven.pkg.github.com/OWNER/REPOSITORY
tomcatjss-8.4.0/revert_update_version.sh 0000775 0000000 0000000 00000001004 14420205342 0020476 0 ustar 00root root 0000000 0000000 #!/bin/bash -e
# Use this script to revert the commit and delete the tag created using the update_version.sh script.
HEAD_TAG=$(git tag --points-at HEAD)
HEAD_COMMIT_MESSAGE=$(git log --format=%B -n 1 HEAD)
UPDATE_COMMIT_MESSAGE="Updating version to"
# Only proceed if the HEAD commit is a version update
if [[ "$HEAD_COMMIT_MESSAGE=" == *"$UPDATE_COMMIT_MESSAGE"* ]]; then
git tag -d "$HEAD_TAG"
git reset --hard HEAD~1
else
echo "The HEAD commit is not a version update, aborting."
exit 1
fi
tomcatjss-8.4.0/sonar-project.properties 0000664 0000000 0000000 00000000660 14420205342 0020434 0 ustar 00root root 0000000 0000000 sonar.projectKey=dogtagpki_tomcatjss
sonar.organization=dogtagpki
# This is the name and version displayed in the SonarCloud UI.
#sonar.projectName=tomcatjss
#sonar.projectVersion=1.0
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
sonar.sources=core/src/main/java/
sonar.java.binaries=build/
# Encoding of the source code. Default is default system encoding
#sonar.sourceEncoding=UTF-8
tomcatjss-8.4.0/tests/ 0000775 0000000 0000000 00000000000 14420205342 0014670 5 ustar 00root root 0000000 0000000 tomcatjss-8.4.0/tests/bin/ 0000775 0000000 0000000 00000000000 14420205342 0015440 5 ustar 00root root 0000000 0000000 tomcatjss-8.4.0/tests/bin/ds-artifacts-save.sh 0000775 0000000 0000000 00000000761 14420205342 0021323 0 ustar 00root root 0000000 0000000 #!/bin/bash
CONTAINER=$1
INSTANCE=$2
if [ "$INSTANCE" == "" ]
then
INSTANCE=localhost
fi
ARTIFACTS=/tmp/artifacts/$CONTAINER
mkdir -p $ARTIFACTS/etc
mkdir -p $ARTIFACTS/var/log
docker exec $CONTAINER ls -la /etc/dirsrv
docker cp $CONTAINER:/etc/dirsrv $ARTIFACTS/etc
docker exec $CONTAINER ls -la /var/log/dirsrv
docker cp $CONTAINER:/var/log/dirsrv $ARTIFACTS/var/log
docker exec $CONTAINER journalctl -u dirsrv@$INSTANCE.service > $ARTIFACTS/var/log/dirsrv/slapd-$INSTANCE/systemd.log
tomcatjss-8.4.0/tests/bin/ds-create.sh 0000775 0000000 0000000 00000001141 14420205342 0017643 0 ustar 00root root 0000000 0000000 #!/bin/bash -ex
# This command needs to be executed as it pulls the machine name
# dynamically.
dscreate create-template ds.inf
sed -i \
-e "s/;instance_name = .*/instance_name = localhost/g" \
-e "s/;root_password = .*/root_password = Secret.123/g" \
-e "s/;suffix = .*/suffix = dc=example,dc=com/g" \
-e "s/;self_sign_cert = .*/self_sign_cert = False/g" \
ds.inf
dscreate from-file ds.inf
ldapadd -H ldap://$HOSTNAME -x -D "cn=Directory Manager" -w Secret.123 << EOF
dn: dc=example,dc=com
objectClass: domain
dc: example
dn: dc=pki,dc=example,dc=com
objectClass: domain
dc: pki
EOF
tomcatjss-8.4.0/tests/bin/ds-remove.sh 0000775 0000000 0000000 00000000066 14420205342 0017702 0 ustar 00root root 0000000 0000000 #!/bin/bash -ex
dsctl slapd-localhost remove --do-it
tomcatjss-8.4.0/tests/bin/init-workflow.sh 0000775 0000000 0000000 00000001612 14420205342 0020612 0 ustar 00root root 0000000 0000000 #!/bin/bash -e
################################################################################
# Base image
if [ "$BASE64_OS" != "" ]
then
OS_VERSION=$(echo "$BASE64_OS" | base64 -d)
else
OS_VERSION=latest
fi
BASE_IMAGE=registry.fedoraproject.org/fedora:$OS_VERSION
echo "BASE_IMAGE: $BASE_IMAGE"
echo "base-image=$BASE_IMAGE" >> $GITHUB_OUTPUT
################################################################################
# COPR repository
if [ "$BASE64_REPO" != "" ]
then
REPO=$(echo "$BASE64_REPO" | base64 -d)
fi
echo "REPO: $REPO"
echo "repo=$REPO" >> $GITHUB_OUTPUT
################################################################################
# Database image
if [ "$BASE64_DATABASE" != "" ]
then
DATABASE=$(echo "$BASE64_DATABASE" | base64 -d)
DB_IMAGE=$(echo "$DATABASE" | jq -r .image)
fi
echo "DB_IMAGE: $DB_IMAGE"
echo "db-image=$DB_IMAGE" >> $GITHUB_OUTPUT
tomcatjss-8.4.0/tests/bin/pki-artifacts-save.sh 0000775 0000000 0000000 00000001056 14420205342 0021476 0 ustar 00root root 0000000 0000000 #!/bin/bash
CONTAINER=$1
INSTANCE=$2
if [ "$INSTANCE" == "" ]
then
INSTANCE=pki-tomcat
fi
ARTIFACTS=/tmp/artifacts/$CONTAINER
mkdir -p $ARTIFACTS/etc/pki
mkdir -p $ARTIFACTS/var/log
docker exec $CONTAINER ls -la /etc/pki
docker cp $CONTAINER:/etc/pki/pki.conf $ARTIFACTS/etc/pki
docker cp $CONTAINER:/etc/pki/$INSTANCE $ARTIFACTS/etc/pki
docker exec $CONTAINER ls -la /var/log/pki
docker cp $CONTAINER:/var/log/pki $ARTIFACTS/var/log
docker exec $CONTAINER journalctl -u pki-tomcatd@$INSTANCE.service > $ARTIFACTS/var/log/pki/$INSTANCE/systemd.log
tomcatjss-8.4.0/tests/bin/rpminspect.sh 0000775 0000000 0000000 00000000612 14420205342 0020162 0 ustar 00root root 0000000 0000000 #!/bin/bash -e
# Don't run metadata check as we can't know the build host subdomain
# of CI runners in advance to add to an allow list
echo "Running RPMInspect on SRPM"
rpminspect-fedora -E metadata build/SRPMS/*.rpm
# Run RPMInspect on RPMs
for f in build/RPMS/*rpm; do
echo "::group::Running RPMInspect on $f"
rpminspect-fedora -E metadata,javabytecode "$f"
echo "::endgroup::"
done
tomcatjss-8.4.0/tests/bin/runner-init.sh 0000775 0000000 0000000 00000000731 14420205342 0020252 0 ustar 00root root 0000000 0000000 #!/bin/bash -ex
docker run \
--name=${NAME} \
--hostname=${HOSTNAME} \
--detach \
--privileged \
--tmpfs /tmp \
--tmpfs /run \
-v ${GITHUB_WORKSPACE}:${SHARED} \
-i \
${IMAGE}
# Pause 5 seconds to let the container start up.
# The container uses /usr/sbin/init as its entrypoint which requires few seconds
# to startup. This avoids the following error:
# [Errno 2] No such file or directory: '/var/cache/dnf/metadata_lock.pid'
sleep 5
tomcatjss-8.4.0/tomcat-9.0/ 0000775 0000000 0000000 00000000000 14420205342 0015321 5 ustar 00root root 0000000 0000000 tomcatjss-8.4.0/tomcat-9.0/pom.xml 0000664 0000000 0000000 00000003013 14420205342 0016633 0 ustar 00root root 0000000 0000000
4.0.0
org.dogtagpki.tomcatjss
tomcatjss-parent
${revision}
tomcatjss-tomcat-9.0
jar
org.apache.tomcat
tomcat-catalina
9.0.50
org.dogtagpki.jss
jss-base
5.4.0-SNAPSHOT
${project.groupId}
tomcatjss-core
${project.version}
org.apache.maven.plugins
maven-compiler-plugin
3.8.1
17
tomcatjss-8.4.0/tomcat-9.0/src/ 0000775 0000000 0000000 00000000000 14420205342 0016110 5 ustar 00root root 0000000 0000000 tomcatjss-8.4.0/tomcat-9.0/src/main/ 0000775 0000000 0000000 00000000000 14420205342 0017034 5 ustar 00root root 0000000 0000000 tomcatjss-8.4.0/tomcat-9.0/src/main/java/ 0000775 0000000 0000000 00000000000 14420205342 0017755 5 ustar 00root root 0000000 0000000 tomcatjss-8.4.0/tomcat-9.0/src/main/java/org/ 0000775 0000000 0000000 00000000000 14420205342 0020544 5 ustar 00root root 0000000 0000000 tomcatjss-8.4.0/tomcat-9.0/src/main/java/org/dogtagpki/ 0000775 0000000 0000000 00000000000 14420205342 0022515 5 ustar 00root root 0000000 0000000 tomcatjss-8.4.0/tomcat-9.0/src/main/java/org/dogtagpki/tomcat/ 0000775 0000000 0000000 00000000000 14420205342 0024004 5 ustar 00root root 0000000 0000000 tomcatjss-8.4.0/tomcat-9.0/src/main/java/org/dogtagpki/tomcat/JSSContext.java 0000664 0000000 0000000 00000007636 14420205342 0026667 0 ustar 00root root 0000000 0000000 package org.dogtagpki.tomcat;
import java.security.KeyManagementException;
import java.security.SecureRandom;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import org.apache.tomcat.util.net.jss.TomcatJSS;
import org.mozilla.jss.JSSProvider;
import org.mozilla.jss.provider.javax.crypto.JSSKeyManager;
import org.mozilla.jss.provider.javax.crypto.JSSTrustManager;
import org.mozilla.jss.ssl.javax.JSSEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JSSContext implements org.apache.tomcat.util.net.SSLContext {
public static Logger logger = LoggerFactory.getLogger(JSSContext.class);
private javax.net.ssl.SSLContext ctx;
private String alias;
private JSSKeyManager jkm;
private JSSTrustManager jtm;
public JSSContext(String alias) {
logger.debug("JSSContext(" + alias + ")");
this.alias = alias;
/* These KeyManagers and TrustManagers aren't used with the SSLEngine;
* they're only used to implement certain function calls below. */
try {
KeyManagerFactory kmf = KeyManagerFactory.getInstance("NssX509", "Mozilla-JSS");
jkm = (JSSKeyManager) kmf.getKeyManagers()[0];
TrustManagerFactory tmf = TrustManagerFactory.getInstance("NssX509", "Mozilla-JSS");
jtm = (JSSTrustManager) tmf.getTrustManagers()[0];
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
@Override
public void init(KeyManager[] kms, TrustManager[] tms, SecureRandom sr) throws KeyManagementException {
logger.debug("JSSContext.init(...)");
try {
String provider = "SunJSSE";
if (JSSProvider.ENABLE_JSSENGINE) {
provider = "Mozilla-JSS";
}
ctx = javax.net.ssl.SSLContext.getInstance("TLS", provider);
ctx.init(kms, tms, sr);
} catch (Exception e) {
throw new KeyManagementException(e.getMessage(), e);
}
}
@Override
public javax.net.ssl.SSLEngine createSSLEngine() {
logger.debug("JSSContext.createSSLEngine()");
javax.net.ssl.SSLEngine eng = ctx.createSSLEngine();
TomcatJSS instance = TomcatJSS.getInstance();
if (eng instanceof JSSEngine) {
JSSEngine j_eng = (JSSEngine) eng;
j_eng.setCertFromAlias(alias);
if(instance != null) {
j_eng.setListeners(instance.getSocketListeners());
}
}
return eng;
}
@Override
public javax.net.ssl.SSLSessionContext getServerSessionContext() {
logger.debug("JSSContext.getServerSessionContext()");
return ctx.getServerSessionContext();
}
@Override
public javax.net.ssl.SSLServerSocketFactory getServerSocketFactory() {
logger.debug("JSSContext.getServerSocketFactory()");
return ctx.getServerSocketFactory();
}
@Override
public javax.net.ssl.SSLParameters getSupportedSSLParameters() {
logger.debug("JSSContext.getSupportedSSLParameters()");
return ctx.getSupportedSSLParameters();
}
@Override
public java.security.cert.X509Certificate[] getCertificateChain(java.lang.String alias) {
logger.debug("JSSContext.getCertificateChain(" + alias + ")");
try {
return jkm.getCertificateChain(alias);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
logger.debug("JSSContext.getAcceptedIssuers()");
try {
return jtm.getAcceptedIssuers();
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
@Override
public void destroy() {
logger.debug("JSSContext.destroy()");
}
}
tomcatjss-8.4.0/tomcat-9.0/src/main/java/org/dogtagpki/tomcat/JSSImplementation.java 0000664 0000000 0000000 00000005051 14420205342 0030215 0 ustar 00root root 0000000 0000000 /* BEGIN COPYRIGHT BLOCK
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Copyright (C) 2007 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK */
package org.dogtagpki.tomcat;
import javax.net.ssl.SSLSession;
import org.apache.tomcat.util.net.SSLHostConfig;
import org.apache.tomcat.util.net.SSLHostConfigCertificate;
import org.apache.tomcat.util.net.SSLImplementation;
import org.apache.tomcat.util.net.SSLSupport;
import org.apache.tomcat.util.net.SSLUtil;
import org.apache.tomcat.util.net.jsse.JSSESupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JSSImplementation extends SSLImplementation {
public static final Logger logger = LoggerFactory.getLogger(JSSImplementation.class);
public JSSImplementation() {
logger.debug("JSSImplementation: instance created");
}
@Override
public SSLSupport getSSLSupport(SSLSession session) {
logger.debug("JSSImplementation.getSSLSupport()");
return new JSSESupport(session, null);
}
@Override
public SSLUtil getSSLUtil(SSLHostConfigCertificate cert) {
logger.debug("JSSImplementation: getSSLUtil()");
logger.debug("JSSImplementation: key alias: {}", cert.getCertificateKeyAlias());
logger.debug("JSSImplementation: keystore provider: {}", cert.getCertificateKeystoreProvider());
SSLHostConfig hostConfig = cert.getSSLHostConfig();
logger.debug("JSSImplementation: key manager alg: {}", hostConfig.getKeyManagerAlgorithm());
logger.debug("JSSImplementation: truststore alg: {}", hostConfig.getTruststoreAlgorithm());
logger.debug("JSSImplementation: truststore provider: {}", hostConfig.getTruststoreProvider());
return new JSSUtil(cert);
}
@Override
public boolean isAlpnSupported() {
// NSS supports ALPN but JSS doesn't yet support ALPN.
return false;
}
}
tomcatjss-8.4.0/tomcat-9.0/src/main/java/org/dogtagpki/tomcat/JSSUtil.java 0000664 0000000 0000000 00000007760 14420205342 0026156 0 ustar 00root root 0000000 0000000 /* BEGIN COPYRIGHT BLOCK
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Copyright (C) 2018 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK */
package org.dogtagpki.tomcat;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.net.SSLContext;
import org.apache.tomcat.util.net.SSLHostConfigCertificate;
import org.apache.tomcat.util.net.SSLUtilBase;
import org.mozilla.jss.JSSProvider;
import org.mozilla.jss.provider.javax.crypto.JSSNativeTrustManager;
public class JSSUtil extends SSLUtilBase {
public static Log logger = LogFactory.getLog(JSSUtil.class);
private String keyAlias;
private SSLEngine engine;
private Set protocols;
private Set ciphers;
public JSSUtil(SSLHostConfigCertificate cert) {
super(cert);
keyAlias = certificate.getCertificateKeyAlias();
logger.debug("JSSUtil: instance created");
}
private void init() {
if (engine != null) {
return;
}
try {
JSSContext ctx = new JSSContext(null);
ctx.init(null, null, null);
engine = ctx.createSSLEngine();
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
protocols = Collections.unmodifiableSet(
new HashSet<>(Arrays.asList(engine.getSupportedProtocols()))
);
ciphers = Collections.unmodifiableSet(
new HashSet<>(Arrays.asList(engine.getSupportedCipherSuites()))
);
}
@Override
public KeyManager[] getKeyManagers() throws Exception {
logger.debug("JSSUtil: getKeyManagers()");
KeyManagerFactory jkm = KeyManagerFactory.getInstance("NssX509", "Mozilla-JSS");
return jkm.getKeyManagers();
}
@Override
public TrustManager[] getTrustManagers() throws Exception {
logger.debug("JSSUtil: getTrustManagers()");
if (!JSSProvider.ENABLE_JSSENGINE) {
TrustManagerFactory tmf = TrustManagerFactory.getInstance("NssX509");
return tmf.getTrustManagers();
}
return new TrustManager[] { new JSSNativeTrustManager() };
}
@Override
public SSLContext createSSLContextInternal(List negotiableProtocols) throws Exception {
logger.debug("JSSUtil createSSLContextInternal(...) keyAlias=" + keyAlias);
return new JSSContext(keyAlias);
}
@Override
public boolean isTls13RenegAuthAvailable() {
logger.debug("JSSUtil: isTls13RenegAuthAvailable()");
return true;
}
@Override
public Log getLog() {
logger.debug("JSSUtil: getLog()");
return logger;
}
@Override
protected Set getImplementedProtocols() {
logger.debug("JSSUtil: getImplementedProtocols()");
init();
return protocols;
}
@Override
protected Set getImplementedCiphers() {
logger.debug("JSSUtil: getImplementedCiphers()");
init();
return ciphers;
}
}
tomcatjss-8.4.0/tomcatjss.spec 0000664 0000000 0000000 00000013347 14420205342 0016421 0 ustar 00root root 0000000 0000000 ################################################################################
Name: tomcatjss
################################################################################
%global product_id dogtag-tomcatjss
# Upstream version number:
%global major_version 8
%global minor_version 4
%global update_version 0
# Downstream release number:
# - development/stabilization (unsupported): 0. where n >= 1
# - GA/update (supported): where n >= 1
%global release_number 1
# Development phase:
# - development (unsupported): alpha where n >= 1
# - stabilization (unsupported): beta where n >= 1
# - GA/update (supported):
#global phase
%undefine timestamp
%undefine commit_id
Summary: JSS Connector for Apache Tomcat
URL: https://github.com/dogtagpki/tomcatjss
License: LGPLv2+
BuildArch: noarch
Version: %{major_version}.%{minor_version}.%{update_version}
Release: %{release_number}%{?phase:.}%{?phase}%{?timestamp:.}%{?timestamp}%{?commit_id:.}%{?commit_id}%{?dist}
# To generate the source tarball:
# $ git clone https://github.com/dogtagpki/tomcatjss.git
# $ cd tomcatjss
# $ git archive \
# --format=tar.gz \
# --prefix tomcatjss-VERSION/ \
# -o tomcatjss-VERSION.tar.gz \
#
Source: https://github.com/dogtagpki/tomcatjss/archive/v%{version}%{?phase:-}%{?phase}/tomcatjss-%{version}%{?phase:-}%{?phase}.tar.gz
# To create a patch for all changes since a version tag:
# $ git format-patch \
# --stdout \
# \
# > tomcatjss-VERSION-RELEASE.patch
# Patch: tomcatjss-VERSION-RELEASE.patch
################################################################################
# Java
################################################################################
%define java_devel java-17-openjdk-devel
%define java_headless java-17-openjdk-headless
%define java_home %{_jvmdir}/jre-17-openjdk
################################################################################
# Build Dependencies
################################################################################
# jpackage-utils requires versioning to meet both build and runtime requirements
# jss requires versioning to meet both build and runtime requirements
# tomcat requires versioning to meet both build and runtime requirements
# Java
BuildRequires: ant
BuildRequires: apache-commons-lang3
BuildRequires: %{java_devel}
BuildRequires: jpackage-utils >= 0:1.7.5-15
# SLF4J
BuildRequires: slf4j
BuildRequires: slf4j-jdk14
# JSS
BuildRequires: jss = 5.4
# Tomcat
%if 0%{?rhel} && ! 0%{?eln}
BuildRequires: pki-servlet-engine >= 1:9.0.7
%else
BuildRequires: tomcat >= 1:9.0.7
%endif
%description
JSS Connector for Apache Tomcat, installed via the tomcatjss package,
is a Java Secure Socket Extension (JSSE) module for Apache Tomcat that
uses Java Security Services (JSS), a Java interface to Network Security
Services (NSS).
################################################################################
%package -n %{product_id}
################################################################################
Summary: JSS Connector for Apache Tomcat
# Java
Requires: apache-commons-lang3
Requires: %{java_headless}
Requires: jpackage-utils >= 0:1.7.5-15
# SLF4J
Requires: slf4j
Requires: slf4j-jdk14
# JSS
Requires: jss = 5.4
# Tomcat
%if 0%{?rhel} && ! 0%{?eln}
Requires: pki-servlet-engine >= 1:9.0.7
%else
Requires: tomcat >= 1:9.0.7
%endif
Obsoletes: tomcatjss < %{version}-%{release}
Provides: tomcatjss = %{version}-%{release}
Provides: tomcatjss = %{major_version}.%{minor_version}
Provides: %{product_id} = %{major_version}.%{minor_version}
# PKI
Conflicts: pki-base < 10.10.0
%if 0%{?rhel}
# For EPEL, override the '_sharedstatedir' macro on RHEL
%define _sharedstatedir /var/lib
%endif
%description -n %{product_id}
JSS Connector for Apache Tomcat, installed via the tomcatjss package,
is a Java Secure Socket Extension (JSSE) module for Apache Tomcat that
uses Java Security Services (JSS), a Java interface to Network Security
Services (NSS).
################################################################################
%prep
################################################################################
%autosetup -n tomcatjss-%{version}%{?phase:-}%{?phase} -p 1
################################################################################
%build
################################################################################
export JAVA_HOME=%{java_home}
./build.sh \
%{?_verbose:-v} \
--name=%{product_id} \
--work-dir=%{_vpath_builddir} \
--version=%{version} \
--jni-dir=%{_jnidir} \
dist
################################################################################
%install
################################################################################
./build.sh \
%{?_verbose:-v} \
--name=%{product_id} \
--work-dir=%{_vpath_builddir} \
--version=%{version} \
--java-dir=%{_javadir} \
--doc-dir=%{_docdir} \
--install-dir=%{buildroot} \
install
################################################################################
%files -n %{product_id}
################################################################################
%license LICENSE
%defattr(-,root,root)
%doc README
%doc LICENSE
%{_javadir}/*
################################################################################
%changelog
* Thu Mar 15 2018 Dogtag PKI Team 7.3.0-0
- To list changes in since :
$ git log --pretty=oneline --abbrev-commit --no-decorate ..
tomcatjss-8.4.0/update_version.sh 0000775 0000000 0000000 00000005776 14420205342 0017133 0 ustar 00root root 0000000 0000000 #!/bin/bash -e
# Use this script to automate updating tomcatjss version.
#
# Usage: ./update_version.sh # (phase is optional)
#
# Explanation:
# - change_spec_version
# - Updates the spec version to the new version provided
# - commit_version_change
# - Commits that change
# - create_tag
# - Creates a tag based on the new version provided
# - create_source_tarball
# - Creates a source tarball based on the new version provided
NEXT_MAJOR=$1
NEXT_MINOR=$2
NEXT_UPDATE=$3
NEXT_PHASE=$4
if [ -z "$NEXT_PHASE" ] ; then
NEXT_VERSION=$NEXT_MAJOR.$NEXT_MINOR.$NEXT_UPDATE
else
NEXT_VERSION=$NEXT_MAJOR.$NEXT_MINOR.$NEXT_UPDATE-$NEXT_PHASE
fi
echo "New version is $NEXT_VERSION"
verify_phase() {
if [[ "$NEXT_PHASE" =~ ^(alpha|beta)[0-9]+$ ]] ; then
echo "$NEXT_PHASE is a valid phase"
elif [ -z "$NEXT_PHASE" ] ; then
echo "Empty phase"
else
echo "$NEXT_PHASE is an invalid phase, aborting"
exit 1
fi
}
change_spec_version() {
CURRENT_PHASE=$(grep "phase " tomcatjss.spec | grep -E 'alpha|beta' | awk '{print $(NF)}')
CURRENT_RELEASE_NUMBER=$(grep "release_number " tomcatjss.spec | grep -Eo '[0-9]+(\.[0-9]+)?$')
echo "Update major version to $NEXT_MAJOR"
sed -i "/major_version /c\%global major_version $NEXT_MAJOR" tomcatjss.spec
echo "Update minor version to $NEXT_MINOR"
sed -i "/minor_version /c\%global minor_version $NEXT_MINOR" tomcatjss.spec
echo "Update update version to $NEXT_UPDATE"
sed -i "/update_version /c\%global update_version $NEXT_UPDATE" tomcatjss.spec
if [[ "$CURRENT_PHASE" != "$NEXT_PHASE" ]] ; then
if [ -z "$NEXT_PHASE" ] ; then
echo "Remove phase"
sed -i "/phase /c\#global phase" tomcatjss.spec
echo "Update release_number"
sed -i "/release_number /c\%global release_number 1" tomcatjss.spec
elif [ -z "$CURRENT_PHASE" ] ; then
echo "Add phase, set to $NEXT_PHASE"
sed -i "/#global phase/c\%global phase $NEXT_PHASE" tomcatjss.spec
echo "Update release_number"
sed -i "/release_number /c\%global release_number 0.1" tomcatjss.spec
else
echo "Update phase to $NEXT_PHASE"
sed -i "/phase /c\%global phase $NEXT_PHASE" tomcatjss.spec
echo "Update release_number"
IFS='.' read -ra CRL <<< "$CURRENT_RELEASE_NUMBER"
(( CRL[1]++ ))
sed -i "/release_number /c\%global release_number ${CRL[0]}.${CRL[1]}" tomcatjss.spec
fi
fi
}
commit_version_change() {
git add tomcatjss.spec
git commit -m "Updating version to v$NEXT_VERSION"
}
create_tag() {
git tag v"$NEXT_VERSION"
}
create_source_tarball() {
./build.sh --source-tag=v"$NEXT_VERSION" src
}
### Perform operations
verify_phase
change_spec_version
commit_version_change
create_tag
create_source_tarball