TimestampParameters.java
/*
* Copyright (C) 2016 Hobrasoft s.r.o.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cz.hobrasoft.pdfmu.operation.signature;
import com.itextpdf.text.pdf.security.TSAClient;
import com.itextpdf.text.pdf.security.TSAClientBouncyCastle;
import static cz.hobrasoft.pdfmu.error.ErrorType.SIGNATURE_ADD_TSA_INVALID_URL;
import cz.hobrasoft.pdfmu.operation.OperationException;
import cz.hobrasoft.pdfmu.operation.args.ArgsConfiguration;
import cz.hobrasoft.pdfmu.operation.args.PasswordArgs;
import java.util.logging.Logger;
import net.sourceforge.argparse4j.inf.ArgumentGroup;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.Namespace;
import org.apache.commons.validator.routines.UrlValidator;
/**
* Parameters of timestamping process.
*
* @author <a href="mailto:filip.bartek@hobrasoft.cz">Filip Bartek</a>
*/
public class TimestampParameters implements ArgsConfiguration {
private static final Logger LOGGER = Logger.getLogger(TimestampParameters.class.getName());
/**
* Timestamp authority URL.
*/
public String url;
/**
* Timestamp authority login username.
*/
public String username;
private final PasswordArgs passwordArgs = new PasswordArgs("TSA password");
private final KeystoreParameters sslKeystore = new KeystoreParameters(SslKeystore.PRIVATE.getName());
private final KeystoreParameters sslTruststore = new KeystoreParameters(SslKeystore.TRUSTSTORE.getName());
@Override
public void addArguments(ArgumentParser parser) {
ArgumentGroup group = parser.addArgumentGroup("timestamp");
// TODO: Add description
group.addArgument("--tsa-url")
.help("timestamp authority URL (set to enable timestamp)")
.type(String.class);
group.addArgument("--tsa-username")
.help("timestamp authority username (set to enable TSA authorization)")
.type(String.class);
passwordArgs.passwordArgument = group.addArgument("--tsa-password")
.help("timestamp authority password (default: <none>)");
passwordArgs.environmentVariableArgument = group.addArgument("--tsa-password-envvar")
.help("timestamp authority password environment variable")
.setDefault("PDFMU_TSA_PASSWORD");
passwordArgs.finalizeArguments();
sslKeystore.fileArgument = group.addArgument("--ssl-keystore")
.help("The keystore file that contains the private keys used for SSL authorization. Must be protected by a non-empty password.");
sslKeystore.typeArgument = group.addArgument("--ssl-keystore-type")
.help("SSL KeyStore type")
.choices(new String[]{"jks", "jceks", "pkcs12"});
sslKeystore.passwordArgs.passwordArgument = group.addArgument("--ssl-keystore-password")
.help("SSL KeyStore password (default: <none>)");
sslKeystore.passwordArgs.environmentVariableArgument = group.addArgument("--ssl-keystore-password-envvar")
.help("SSL KeyStore password environment variable")
.setDefault("PDFMU_SSL_KEYSTORE_PASSWORD");
sslKeystore.finalizeArguments();
sslTruststore.fileArgument = group.addArgument("--ssl-truststore")
.help("The keystore file that contains the certificates of the trusted certificate authorities");
// TODO: Add support for type "pkcs12"
sslTruststore.typeArgument = group.addArgument("--ssl-truststore-type")
.help("SSL TrustStore type")
.choices(new String[]{"jks", "jceks"});
sslTruststore.passwordArgs.passwordArgument = group.addArgument("--ssl-truststore-password")
.help("SSL TrustStore password (default: <none>)");
sslTruststore.passwordArgs.environmentVariableArgument = group.addArgument("--ssl-truststore-password-envvar")
.help("SSL TrustStore password environment variable")
.setDefault("PDFMU_SSL_TRUSTSTORE_PASSWORD");
sslTruststore.finalizeArguments();
}
@Override
public void setFromNamespace(Namespace namespace) throws OperationException {
url = namespace.get("tsa_url");
if (url != null) {
UrlValidator urlValidator = new UrlValidator();
if (!urlValidator.isValid(url)) {
throw new OperationException(SIGNATURE_ADD_TSA_INVALID_URL);
}
}
username = namespace.getString("tsa_username");
passwordArgs.setFromNamespace(namespace);
sslKeystore.setFromNamespace(namespace);
if (sslKeystore.file != null) {
String password = sslKeystore.getPassword();
if (password == null || password.isEmpty()) {
LOGGER.warning("SSL KeyStore: Location has been set but password has not. Only KeyStores protected by a non-empty password are supported.");
}
}
sslKeystore.setSystemProperties(SslKeystore.PRIVATE);
sslTruststore.setFromNamespace(namespace);
sslTruststore.setSystemProperties(SslKeystore.TRUSTSTORE);
}
/**
* Returns the {@link TSAClient} that corresponds to these parameters.
*
* @return null if the timestamp authority has not been configured
*/
public TSAClient getTSAClient() {
if (url == null) {
return null;
}
LOGGER.info("TSA URL has been set. Will attempt to attach a timestamp to the signature.");
String password = getPassword();
if (username != null && password == null) {
LOGGER.warning("TSA username has been set but password has not.");
}
if (password != null && username == null) {
LOGGER.warning("TSA password has been set but username has not.");
}
return new TSAClientBouncyCastle(url, username, password);
}
private String getPassword() {
assert passwordArgs != null;
return passwordArgs.getPassword();
}
}