use of org.xipki.util.http.SslContextConf in project xipki by xipki.
the class CaServerConf method getSslContextConf.
public synchronized SslContextConf getSslContextConf(String name) {
if (sslContexts == null || sslContexts.isEmpty()) {
return null;
}
if (sslContextConfMap.isEmpty()) {
for (SslContext m : sslContexts) {
SslContextConf conf = new SslContextConf();
conf.setSslHostnameVerifier(m.getHostverifier());
KeystoreConf truststore = m.getTruststore();
conf.setSslTruststore(truststore.getKeystore());
conf.setSslTruststorePassword(truststore.getPassword());
conf.setSslStoreType(truststore.getType());
sslContextConfMap.put(m.getName(), conf);
}
}
return sslContextConfMap.get(name);
}
use of org.xipki.util.http.SslContextConf in project xipki by xipki.
the class CmpClientConfigurer method init.
// method initIfNotInitialized
synchronized boolean init() {
// reset
this.casMap.clear();
this.autoConfCaNames.clear();
if (this.scheduledThreadPoolExecutor != null) {
this.scheduledThreadPoolExecutor.shutdownNow();
}
this.initialized.set(false);
LOG.info("initializing ...");
File configFile = new File(IoUtil.expandFilepath(confFile));
if (!configFile.exists()) {
LOG.error("could not find configuration file {}", confFile);
return false;
}
CmpClientConf conf;
try {
conf = parse(Files.newInputStream(configFile.toPath()));
} catch (IOException | CmpClientException ex) {
LOG.error("could not read file {}", confFile);
return false;
}
if (CollectionUtil.isEmpty(conf.getCas())) {
LOG.warn("no CA is configured");
}
// ssl configurations
Map<String, SslConf> sslConfs = new HashMap<>();
if (conf.getSsls() != null) {
for (CmpClientConf.Ssl ssl : conf.getSsls()) {
SslContextConf sslCc = new SslContextConf();
sslCc.setSslStoreType(ssl.getStoreType());
try {
if (ssl.getKeystore() != null) {
sslCc.setSslKeystore(ssl.getKeystore());
sslCc.setSslKeystorePassword(ssl.getKeystorePassword());
}
if (ssl.getTrustanchors() != null) {
sslCc.setSslTrustanchors(ssl.getTrustanchors());
}
sslCc.setSslHostnameVerifier(ssl.getHostnameVerifier());
SSLSocketFactory socketFactory = sslCc.getSslSocketFactory();
HostnameVerifier hostnameVerifier = sslCc.buildHostnameVerifier();
sslConfs.put(ssl.getName(), new SslConf(socketFactory, hostnameVerifier));
} catch (ObjectCreationException ex) {
LOG.error("could not initialize SSL configuration " + ssl.getName() + ": " + ex.getMessage(), ex);
return false;
}
}
}
// responders
Map<String, Responder> responders = new HashMap<>();
for (CmpClientConf.Responder m : conf.getResponders()) {
X509Cert cert;
try {
cert = X509Util.parseCert(m.getCert().readContent());
} catch (CertificateException | IOException ex) {
LogUtil.error(LOG, ex, "could not configure responder " + m.getName());
return false;
}
Responder responder;
if (m.getSignature() != null) {
Set<String> algoNames = new HashSet<>(m.getSignature().getSignatureAlgos());
Set<SignAlgo> algos = new HashSet<>();
for (String algoName : algoNames) {
SignAlgo sa;
try {
sa = SignAlgo.getInstance(algoName);
} catch (NoSuchAlgorithmException ex) {
LOG.warn("algorithm is not supported {}, ignore it", algoName);
continue;
}
algos.add(sa);
}
AlgorithmValidator sigAlgoValidator;
try {
if (algos.isEmpty()) {
throw new NoSuchAlgorithmException("none of the signature algorithms " + algoNames + " are supported");
}
sigAlgoValidator = new CollectionAlgorithmValidator(algos);
} catch (NoSuchAlgorithmException ex) {
LogUtil.error(LOG, ex, "could not initialize CollectionAlgorithmValidator");
return false;
}
responder = new Responder.SignatureCmpResponder(cert, sigAlgoValidator);
} else {
// if (m.getPbmMac() != null)
CmpClientConf.Responder.PbmMac mac = m.getPbmMac();
X500Name subject = cert.getSubject();
try {
responder = new Responder.PbmMacCmpResponder(subject, mac.getOwfAlgos(), mac.getMacAlgos());
} catch (NoSuchAlgorithmException ex) {
LogUtil.error(LOG, ex, "could not initialize PbmMacCmpResponder");
return false;
}
}
responders.put(m.getName(), responder);
}
// CA;
Set<CaConf> cas = new HashSet<>();
for (CmpClientConf.Ca caType : conf.getCas()) {
String caName = caType.getName();
try {
// responder
Responder responder = responders.get(caType.getResponder());
if (responder == null) {
LOG.error("no responder named {} is configured", caType.getResponder());
return false;
}
SSLSocketFactory sslSocketFactory = null;
HostnameVerifier hostnameVerifier = null;
if (caType.getSsl() != null) {
SslConf sslConf = sslConfs.get(caType.getSsl());
if (sslConf == null) {
LOG.error("no ssl named {} is configured", caType.getSsl());
return false;
} else {
sslSocketFactory = sslConf.sslSocketFactory;
hostnameVerifier = sslConf.hostnameVerifier;
}
}
CaConf ca = new CaConf(caName, caType.getUrl(), caType.getHealthUrl(), caType.getRequestor(), responder, sslSocketFactory, hostnameVerifier);
// CA certchain
Certs caCertchain = caType.getCaCertchain();
if (caCertchain == null || caCertchain.isAutoconf()) {
ca.setCertAutoconf(true);
} else {
ca.setCertAutoconf(false);
List<FileOrBinary> certchainConf = caType.getCaCertchain().getCertificates();
X509Cert caCert = X509Util.parseCert(certchainConf.get(0).readContent());
Set<X509Cert> issuers = new HashSet<>();
int size = certchainConf.size();
if (size > 1) {
for (int i = 1; i < size; i++) {
X509Cert cert = X509Util.parseCert(certchainConf.get(i).readContent());
issuers.add(cert);
}
X509Cert[] certchain = X509Util.buildCertPath(caCert, issuers);
if (certchain.length != size) {
LOG.error("cannot build certpath containing all configured issuers");
}
ca.setCertchain(Arrays.asList(certchain));
} else {
ca.setCertchain(Collections.singletonList(caCert));
}
}
// DHPop
Certs dhpopCerts = caType.getDhpopCerts();
if (dhpopCerts == null || dhpopCerts.isAutoconf()) {
ca.setDhpopAutoconf(true);
} else {
ca.setDhpopAutoconf(false);
List<X509Cert> certs = new LinkedList<>();
List<FileOrBinary> list = dhpopCerts.getCertificates();
if (list != null) {
for (FileOrBinary m : list) {
X509Cert cert = X509Util.parseCert(m.readContent());
certs.add(cert);
}
}
ca.setDhpopCerts(certs);
}
// CMPControl
CmpClientConf.Cmpcontrol cmpCtrlType = caType.getCmpcontrol();
if (cmpCtrlType == null || cmpCtrlType.isAutoconf()) {
ca.setCmpControlAutoconf(true);
} else {
ca.setCmpControlAutoconf(false);
Boolean tmpBo = cmpCtrlType.getRrAkiRequired();
CaConf.CmpControl control = new CaConf.CmpControl(tmpBo != null && tmpBo);
ca.setCmpControl(control);
}
// Certprofiles
CmpClientConf.Certprofiles certprofilesType = caType.getCertprofiles();
if (certprofilesType == null || certprofilesType.isAutoconf()) {
ca.setCertprofilesAutoconf(true);
} else {
ca.setCertprofilesAutoconf(false);
List<CmpClientConf.Certprofile> types = certprofilesType.getProfiles();
Set<CertprofileInfo> profiles = new HashSet<>(types.size());
for (CmpClientConf.Certprofile m : types) {
String conf0 = null;
if (m.getConf() != null) {
conf0 = m.getConf().getValue();
if (conf0 == null) {
conf0 = StringUtil.toUtf8String(IoUtil.read(m.getConf().getFile()));
}
}
CertprofileInfo profile = new CertprofileInfo(m.getName(), m.getType(), conf0);
profiles.add(profile);
}
ca.setCertprofiles(profiles);
}
cas.add(ca);
if (ca.isCertAutoconf() || ca.isCertprofilesAutoconf() || ca.isCmpControlAutoconf() || ca.isDhpopAutoconf()) {
autoConfCaNames.add(caName);
}
} catch (IOException | CertificateException | CertPathBuilderException ex) {
LogUtil.error(LOG, ex, "could not configure CA " + caName);
return false;
}
}
// requestors
Map<String, Requestor> requestors = new HashMap<>();
for (CmpClientConf.Requestor requestorConf : conf.getRequestors()) {
boolean signRequest = requestorConf.isSignRequest();
String name = requestorConf.getName();
Requestor requestor;
if (requestorConf.getSignature() != null) {
CmpClientConf.Requestor.Signature cf = requestorConf.getSignature();
// requestorSignRequests.put(name, cf.isSignRequest());
X509Cert requestorCert = null;
if (cf.getCert() != null) {
try {
requestorCert = X509Util.parseCert(cf.getCert().getBinary());
} catch (Exception ex) {
LogUtil.error(LOG, ex, "could not parse certificate of rquestor " + requestorConf.getName());
return false;
}
}
if (cf.getSignerType() != null) {
try {
SignerConf signerConf = new SignerConf(cf.getSignerConf());
ConcurrentContentSigner requestorSigner = securityFactory.createSigner(cf.getSignerType(), signerConf, requestorCert);
requestor = new SignatureCmpRequestor(signRequest, requestorSigner);
} catch (ObjectCreationException ex) {
LogUtil.error(LOG, ex, "could not create rquestor " + requestorConf.getName());
return false;
}
} else {
if (signRequest) {
LOG.error("signer of requestor must be configured");
return false;
} else if (requestorCert == null) {
LOG.error("at least one of certificate and signer of requestor must be configured");
return false;
} else {
requestor = new SignatureCmpRequestor(requestorCert);
}
}
} else {
CmpClientConf.Requestor.PbmMac cf = requestorConf.getPbmMac();
HashAlgo owfAlgo;
try {
owfAlgo = HashAlgo.getInstance(cf.getOwf());
} catch (NoSuchAlgorithmException ex1) {
LOG.error("Unknown OWF algorithm {}", cf.getOwf());
return false;
}
SignAlgo macAlgo;
try {
macAlgo = SignAlgo.getInstance(cf.getMac());
} catch (NoSuchAlgorithmException ex) {
LOG.error("Unknown MAC algorithm {}", cf.getMac());
return false;
}
requestor = new PbmMacCmpRequestor(signRequest, NULL_GENERALNAME, cf.getPassword().toCharArray(), cf.getKid(), owfAlgo, cf.getIterationCount(), macAlgo);
}
requestors.put(name, requestor);
}
for (CaConf ca : cas) {
if (this.casMap.containsKey(ca.getName())) {
LOG.error("duplicate CAs with the same name {}", ca.getName());
return false;
}
String requestorName = ca.getRequestorName();
if (requestors.containsKey(requestorName)) {
CmpAgent agent = new CmpAgent(requestors.get(requestorName), ca.getResponder(), ca.getUrl(), securityFactory, ca.getSslSocketFactory(), ca.getHostnameVerifier());
ca.setAgent(agent);
} else {
LOG.error("could not find requestor named {} for CA {}", requestorName, ca.getName());
return false;
}
this.casMap.put(ca.getName(), ca);
}
if (!autoConfCaNames.isEmpty()) {
Integer caInfoUpdateInterval = conf.getCainfoUpdateInterval();
if (caInfoUpdateInterval == null) {
caInfoUpdateInterval = 10;
} else if (caInfoUpdateInterval <= 0) {
caInfoUpdateInterval = 0;
} else if (caInfoUpdateInterval < 5) {
caInfoUpdateInterval = 5;
}
LOG.info("configuring CAs {}", autoConfCaNames);
Set<String> failedCaNames = autoConfCas(autoConfCaNames);
if (CollectionUtil.isNotEmpty(failedCaNames)) {
LOG.error("could not configure following CAs {}", failedCaNames);
return false;
}
if (caInfoUpdateInterval > 0) {
scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);
scheduledThreadPoolExecutor.scheduleAtFixedRate(new ClientConfigUpdater(), caInfoUpdateInterval, caInfoUpdateInterval, TimeUnit.MINUTES);
}
}
initialized.set(true);
LOG.info("initialized");
return true;
}
use of org.xipki.util.http.SslContextConf in project xipki by xipki.
the class CaServerConf method initSsl.
public void initSsl() throws CaMgmtException {
if (sslContexts == null || sslContexts.isEmpty()) {
return;
}
if (sslContextConfMap.isEmpty()) {
for (SslContext m : sslContexts) {
SslContextConf conf = new SslContextConf();
conf.setSslHostnameVerifier(m.getHostverifier());
conf.setSslTrustanchors(m.trustanchors);
try {
conf.getSslContext();
} catch (ObjectCreationException e) {
throw new RuntimeException(e);
}
sslContextConfMap.put(m.getName(), conf);
}
}
}
use of org.xipki.util.http.SslContextConf in project xipki by xipki.
the class Ca2Manager method startCa.
// method restartCa
boolean startCa(String caName) {
CaInfo caEntry = manager.caInfos.get(caName);
CtlogControl ctlogControl = caEntry.getCtlogControl();
CtLogClient ctlogClient = null;
if (ctlogControl != null && ctlogControl.isEnabled()) {
String name = ctlogControl.getSslContextName();
SslContextConf ctxConf;
if (name == null) {
ctxConf = null;
} else {
ctxConf = manager.caServerConf.getSslContextConf(name);
if (ctxConf == null) {
LOG.error(concat("getSslContextConf (ca=", caName, "): found no SslContext named " + name));
return false;
}
}
ctlogClient = new CtLogClient(ctlogControl.getServers(), ctxConf);
}
X509Ca ca;
try {
ca = new X509Ca(manager, caEntry, manager.certstore, ctlogClient);
} catch (OperationException ex) {
LogUtil.error(LOG, ex, concat("X509CA.<init> (ca=", caName, ")"));
return false;
}
manager.x509cas.put(caName, ca);
CmpResponder caResponder;
try {
caResponder = new CmpResponder(manager, caName);
} catch (NoSuchAlgorithmException ex) {
LogUtil.error(LOG, ex, concat("CmpResponder.<init> (ca=", caName, ")"));
return false;
}
manager.cmpResponders.put(caName, caResponder);
if (caEntry.getScepResponderName() != null) {
try {
manager.scepResponders.put(caName, new ScepResponder(manager, caEntry.getCaEntry()));
} catch (CaMgmtException ex) {
LogUtil.error(LOG, ex, concat("ScepResponder.<init> (ca=", caName, ")"));
return false;
}
}
return true;
}
use of org.xipki.util.http.SslContextConf in project xipki by xipki.
the class CrlDbCertStatusStore method downloadCrl.
// method updateStore
// Download CRL
private void downloadCrl(File subDir) throws Exception {
if (new File(subDir, "REMOVEME").exists()) {
// CA is removed, no download will be processed.
return;
}
Properties revocationProps = loadProperties(new File(subDir, "REVOCATION"));
if (null != revocationProps.getProperty("ca.revocation.time")) {
// CA is revoked, no download will be processed.
return;
}
File generatedDir = new File(subDir, ".generated");
File updatemeFile = new File(generatedDir, "UPDATEME");
if (updatemeFile.exists()) {
// the last CRL is waiting for the processing
return;
}
File crlInfoFile = new File(generatedDir, "ca.crl.info");
Date nextUpdate;
BigInteger crlNumber = null;
File crlDownloadFile = new File(subDir, "crl.download");
File updateMeNowFile = new File(subDir, "UPDATEME_NOW");
boolean downloadCrl = false;
String hashAlgo = null;
byte[] hashValue = null;
if (!crlInfoFile.exists()) {
// no CRL is available
downloadCrl = true;
} else if (updateMeNowFile.exists()) {
// force download
downloadCrl = true;
} else {
// Check if there exists fresher CRL
Properties props = loadProperties(crlInfoFile);
nextUpdate = DateUtil.parseUtcTimeyyyyMMddhhmmss(props.getProperty("nextupdate"));
crlNumber = new BigInteger(props.getProperty("crlnumber"));
String[] tokens = props.getProperty("hash").split(" ");
hashAlgo = tokens[0];
hashValue = Hex.decode(tokens[1]);
props = loadProperties(crlDownloadFile);
Validity validity = Validity.getInstance(props.getProperty("download.before.nextupdate"));
if (validity.getValidity() < 1) {
LOG.error("invalid download.before.nextupdate {}", validity);
} else {
if (validity.add(new Date()).after(nextUpdate)) {
downloadCrl = true;
}
}
}
if (!downloadCrl) {
return;
}
Properties props = loadProperties(crlDownloadFile);
String downloadUrl = props.getProperty("download.url");
if (downloadUrl == null) {
downloadUrl = props.getProperty("crldp");
}
if (StringUtil.isBlank(downloadUrl)) {
LOG.error("Neither download.url nor crldp in {} is specified, skip it", crlDownloadFile.getPath());
return;
}
String str = props.getProperty("download.fp.url");
String hashUrl = null;
if (str != null) {
String[] tokens = str.split(" ");
if (hashValue != null && !hashAlgo.equalsIgnoreCase(tokens[0])) {
// ignore the stored hash value
hashValue = null;
}
hashAlgo = tokens[0];
hashUrl = tokens[1];
}
String subDirPath = subDir.getPath();
Curl curl = curls.get(subDirPath);
File trustanchorFile = new File(subDir, "tls-trustanchor.pem");
if (trustanchorFile.exists()) {
if (curl != null) {
long lastModified = curlsConfLastModified.get(subDirPath);
if (trustanchorFile.lastModified() != lastModified) {
curl = null;
curlsConfLastModified.remove(subDirPath);
curls.remove(subDirPath);
}
}
if (curl == null) {
SslContextConf sslContextConf = new SslContextConf();
sslContextConf.setSslTrustanchors(trustanchorFile.getPath());
curl = new DefaultCurl(sslContextConf);
curls.put(subDirPath, curl);
curlsConfLastModified.put(subDirPath, trustanchorFile.lastModified());
}
} else {
if (curl == null) {
curl = new DefaultCurl(null);
curls.put(subDirPath, curl);
curlsConfLastModified.put(subDirPath, 0L);
}
}
// download the fingerprint if download.fp.url is specified
if (hashUrl != null) {
Curl.CurlResult downResult = curl.curlGet(hashUrl, false, null, null);
if (downResult.getContentLength() > 0 && Arrays.equals(hashValue, downResult.getContent())) {
LOG.info("Fingerprint of the CRL has not changed, skip downloading CRL");
return;
}
}
File tmpCrlFile = new File(generatedDir, "tmp-ca.crl");
CompositeOutputStream crlStream = new CompositeOutputStream(hashAlgo == null ? null : HashAlgo.getInstance(hashAlgo), new FileOutputStream(tmpCrlFile));
Curl.CurlResult downResult;
try {
downResult = curl.curlGet(downloadUrl, crlStream, false, null, null);
} finally {
crlStream.close();
}
String contentType = downResult.getContentType();
if (!CT_PKIX_CRL.equals(contentType)) {
LOG.error("Downloading CRL failed, expected content type {}, but received {}", CT_PKIX_CRL, contentType);
return;
}
if (downResult.getContentLength() < 10) {
byte[] errorContent = downResult.getErrorContent();
if (errorContent == null) {
LOG.error("Downloading CRL failed, CRL too short (len={}): ", downResult.getContentLength());
} else {
LOG.error("Downloading CRL failed with error: {}", new String(errorContent));
}
return;
}
// Extract CRLNumber from the CRL
CrlStreamParser newCrlStreamParser = new CrlStreamParser(tmpCrlFile);
BigInteger newCrlNumber = newCrlStreamParser.getCrlNumber();
boolean useNewCrl = crlNumber == null || newCrlNumber.compareTo(crlNumber) > 0;
if (useNewCrl) {
String hashProp = hashAlgo + " " + Hex.encode(crlStream.getHashValue());
IoUtil.save(new File(generatedDir, "new-ca.crl.fp"), hashProp.getBytes(StandardCharsets.UTF_8));
tmpCrlFile.renameTo(new File(generatedDir, "new-ca.crl"));
if (crlNumber == null) {
LOG.info("Downloaded CRL at first time");
} else {
LOG.info("Downloaded CRL is newer than existing one");
}
// notify the change
updatemeFile.createNewFile();
} else {
tmpCrlFile.delete();
LOG.info("Downloaded CRL is not newer than existing one");
}
updateMeNowFile.delete();
}
Aggregations