package com.sun.deploy.security;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.AccessController;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.Collection;
import java.util.Enumeration;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import java.util.TreeSet;
import java.util.HashSet;
import com.sun.deploy.util.Trace;
import com.sun.deploy.config.Config;
import com.sun.deploy.resources.ResourceManager;
import com.sun.deploy.ui.UIFactory;
import java.net.PasswordAuthentication;
public final class DeploySigningCertStore implements CertStore
{
private static String _userFilename = null;
private static String _systemFilename = null;
private long _userLastModified = 0;
private long _sysLastModified = 0;
private KeyStore _deploymentUserCerts = CertUtils.createEmptyKeyStore();
private KeyStore _deploymentSystemCerts = CertUtils.createEmptyKeyStore();
private char[] keyPassphrase = new char[0];
private boolean cancelFlag = false;
private int certStoreType = 0;
static
{
_userFilename = Config.getUserTrustedCertificateFile();
_systemFilename = Config.getSystemTrustedCertificateFile();
}
private DeploySigningCertStore(int storeType) {
certStoreType = storeType;
}
public static CertStore getCertStore() {
return new ImmutableCertStore(new DeploySigningCertStore(CertStore.ALL));
}
public static CertStore getUserCertStore() {
return new DeploySigningCertStore(CertStore.USER);
}
public static CertStore getSystemCertStore() {
return new ImmutableCertStore(new DeploySigningCertStore(CertStore.SYSTEM));
}
public void load() throws IOException, CertificateException,
KeyStoreException, NoSuchAlgorithmException
{
load(false);
}
public void load(boolean integrityCheck) throws
IOException, CertificateException,
KeyStoreException, NoSuchAlgorithmException
{
long lastModified;
if ((certStoreType & CertStore.USER) == CertStore.USER) {
if (_userFilename != null) {
lastModified = CertUtils.getFileLastModified(_userFilename);
if (lastModified != _userLastModified) {
_deploymentUserCerts = loadCertStore(_userFilename, integrityCheck);
_userLastModified = lastModified;
}
}
}
if ((certStoreType & CertStore.SYSTEM) == CertStore.SYSTEM) {
if (_systemFilename != null) {
lastModified = CertUtils.getFileLastModified(_systemFilename);
if (lastModified != _sysLastModified) {
_deploymentSystemCerts = loadCertStore(_systemFilename, integrityCheck);
_sysLastModified = lastModified;
}
}
}
}
private KeyStore loadCertStore(final String filename, final boolean integrityCheck)
throws IOException, CertificateException,
KeyStoreException, NoSuchAlgorithmException
{
Trace.msgSecurityPrintln("deploycertstore.cert.loading",
new Object[] {filename});
final File file = new File(filename);
final KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null, null);
try
{
AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws IOException, CertificateException,
KeyStoreException, NoSuchAlgorithmException
{
if (file.exists())
{
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
if (integrityCheck) {
cancelFlag = false;
keyStore.load(bis, new char[0]);
}
else {
keyStore.load(bis, null);
}
bis.close();
fis.close();
}
return null;
}
});
}
catch (PrivilegedActionException e)
{
Exception ex = e.getException();
if (ex instanceof IOException) {
if (integrityCheck) {
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
CredentialInfo passwordInfo =
UIFactory.showPasswordDialog(null,
ResourceManager.getMessage("password.dialog.title"),
ResourceManager.getMessage(
"deploycertstore.password.dialog.text"),
false, false, null, false);
if ( passwordInfo != null) {
cancelFlag = false;
keyPassphrase = passwordInfo.getPassword();
keyStore.load(bis, keyPassphrase);
}
else {
cancelFlag = true;
}
bis.close();
fis.close();
}
else {
throw (IOException)ex;
}
}
else if (ex instanceof CertificateException)
throw (CertificateException)ex;
else if (ex instanceof KeyStoreException)
throw (KeyStoreException)ex;
else if (ex instanceof NoSuchAlgorithmException)
throw (NoSuchAlgorithmException)ex;
else
Trace.securityPrintException(e);
}
Trace.msgSecurityPrintln("deploycertstore.cert.loaded",
new Object[]{filename});
return keyStore;
}
public void save() throws IOException, CertificateException,
KeyStoreException, NoSuchAlgorithmException
{
Trace.msgSecurityPrintln("deploycertstore.cert.saving",
new Object[]{_userFilename});
try
{
AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws IOException, CertificateException,
KeyStoreException, NoSuchAlgorithmException
{
File file = new File(_userFilename);
file.getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
_deploymentUserCerts.store(bos, keyPassphrase);
bos.close();
fos.close();
return null;
}
});
}
catch (PrivilegedActionException e)
{
Exception ex = e.getException();
if (ex instanceof IOException)
throw (IOException)ex;
else if (ex instanceof CertificateException)
throw (CertificateException)ex;
else if (ex instanceof KeyStoreException)
throw (KeyStoreException)ex;
else if (ex instanceof NoSuchAlgorithmException)
throw (NoSuchAlgorithmException)ex;
else
Trace.securityPrintException(e);
}
Trace.msgSecurityPrintln("deploycertstore.cert.saved",
new Object[] {_userFilename});
}
public boolean add(Certificate cert) throws KeyStoreException
{
return add(cert, false);
}
public boolean add(Certificate cert, boolean tsFlag) throws KeyStoreException
{
Trace.msgSecurityPrintln("deploycertstore.cert.adding");
if (cancelFlag) {
return false;
}
String oldAlias = _deploymentUserCerts.getCertificateAlias(cert);
boolean certNotExist = true;
if (oldAlias != null) {
try {
if ( tsFlag || (oldAlias.indexOf(TSFLAG) == -1)) {
certNotExist = false;
}
else {
remove(cert);
}
}
catch (IOException ioe)
{ Trace.securityPrintException(ioe); }
}
if (certNotExist)
{
Random rand = new Random();
String alias = null;
while (true) {
if (tsFlag) {
alias = "deploymentusercert" + TSFLAG + rand.nextLong();
}
else {
alias = "deploymentusercert" + rand.nextLong();
}
if (_deploymentUserCerts.getCertificate(alias) == null)
break;
}
_deploymentUserCerts.setCertificateEntry(alias, cert);
Trace.msgSecurityPrintln("deploycertstore.cert.added",
new Object[]{ alias});
}
return true;
}
public boolean remove(Certificate cert) throws IOException, KeyStoreException
{
if (cancelFlag) {
return false;
}
Trace.msgSecurityPrintln("deploycertstore.cert.removing");
String alias = _deploymentUserCerts.getCertificateAlias(cert);
if (alias != null)
_deploymentUserCerts.deleteEntry(alias);
Trace.msgSecurityPrintln("deploycertstore.cert.removed", new Object[] {alias});
return true;
}
public boolean contains(Certificate cert) throws KeyStoreException
{
return contains(cert, false);
}
public boolean contains(Certificate cert, boolean tsFlag) throws KeyStoreException
{
Trace.msgSecurityPrintln("deploycertstore.cert.instore");
String alias = _deploymentUserCerts.getCertificateAlias(cert);
if (alias != null && ( !tsFlag || alias.indexOf(TSFLAG) > -1)) {
return true;
}
alias = _deploymentSystemCerts.getCertificateAlias(cert);
return (alias != null && (!tsFlag || alias.indexOf(TSFLAG) > -1));
}
public boolean verify(Certificate cert)
{
Trace.msgSecurityPrintln("deploycertstore.cert.canverify");
return false;
}
public Collection getCertificates() throws KeyStoreException
{
HashSet deploySigningCerts = new HashSet();
if ((certStoreType & CertStore.USER) == CertStore.USER) {
deploySigningCerts.addAll(getCertificates(CertStore.USER));
}
if ((certStoreType & CertStore.SYSTEM) == CertStore.SYSTEM) {
deploySigningCerts.addAll(getCertificates(CertStore.SYSTEM));
}
return deploySigningCerts;
}
private Collection getCertificates(int myCertStoreType) throws KeyStoreException
{
Trace.msgSecurityPrintln("deploycertstore.cert.getcertificates");
Collection certCollection = new ArrayList();
KeyStore ks = null;
if (myCertStoreType == CertStore.USER) {
ks = _deploymentUserCerts;
}
else {
ks = _deploymentSystemCerts;
}
Enumeration keyAliases = ks.aliases();
TreeSet tsCerts = new TreeSet();
while (keyAliases.hasMoreElements())
{
String alias = (String) keyAliases.nextElement();
tsCerts.add(alias);
}
Iterator itrCerts = tsCerts.iterator();
while (itrCerts.hasNext())
{
String sortAlias = (String) itrCerts.next();
Certificate cert = ks.getCertificate(sortAlias);
certCollection.add(cert);
}
return certCollection;
}
}