package es.uji.security.keystore.clauer;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.Vector;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMReader;
import es.uji.security.util.HexEncoder;
public class Clauer
{
private ClauerRunTime clRunTime = new ClauerRunTime();
private ClauerHandle clHandle = new ClauerHandle();
public byte TYPE_PEM_PRIVATE_KEY = 1;
public byte TYPE_OWN_CERTIFICATE = 2;
private boolean _initialized = false;
private boolean _isAuth = false;
private boolean _cached = false;
private Vector<String> aliases = new Vector<String>();
private Vector<Certificate> certs = new Vector<Certificate>();
public Clauer()
{
}
private void _installBCprovider(){
// Install BC Provider
// We need it for the PEMReader Object.
if (Security.getProvider("BC") == null)
{
BouncyCastleProvider bcp = new BouncyCastleProvider();
Security.addProvider(bcp);
System.out.println("Added BC provider....");
}
}
public void open(String device) throws IOException, Exception
{
String[] devs = clRunTime.enumerateDevices();
boolean ok = false;
for (int i = 0; i < devs.length; i++)
{
if (device.equals(devs[i]))
{
ok = true;
}
}
if (!ok)
{
throw new Exception("InvalidDeviceName:" + device);
}
clRunTime.startSession(device, "", clHandle);
_isAuth = false;
_initialized = true;
}
public boolean openAuth(String device, String password) throws IOException, Exception
{
String[] devs = clRunTime.enumerateDevices();
boolean ok = false;
for (int i = 0; i < devs.length; i++)
{
if (device.equals(devs[i]))
{
ok = true;
}
}
if (!ok)
{
throw new Exception("InvalidDeviceName:" + device);
}
if (password != null && !password.equals("")
&& clRunTime.startSession(device, password, clHandle))
{
_isAuth = true;
_initialized = true;
return true;
}
return false;
}
public boolean isAuthSession()
{
return _isAuth;
}
public boolean close() throws IOException
{
clRunTime.closeSession();
_initialized = false;
_isAuth = false;
return true;
}
public String[] getCertificateAliases() throws Exception
{
if (!_initialized)
{
throw new Exception("UninitializedClauer");
}
byte[][] blocks = clRunTime.readAllTypeObjects(this.TYPE_OWN_CERTIFICATE);
String[] sRes = new String[blocks.length];
HexEncoder hex = new HexEncoder();
aliases.clear();
certs.clear();
for (int i = 0; i < blocks.length; i++)
{
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = null;
ByteArrayOutputStream bOs = new ByteArrayOutputStream();
hex.encode(blocks[i], 8 + 4 + 31, 20, bOs);
sRes[i] = bOs.toString();
aliases.add(sRes[i]);
ByteArrayInputStream certIs = new ByteArrayInputStream(blocks[i]);
DataInputStream dis = new DataInputStream(certIs);
/* Take out the header */
dis.readInt();
dis.readInt();
int tam = Integer.reverseBytes(dis.readInt());
/* Take out irrelevant info */
for (int j = 0; j < 51; j++)
{
dis.read();
}
/* Read certificate information */
byte[] bCert = new byte[tam];
dis.read(bCert, 0, tam);
ByteArrayInputStream certAuxIs = new ByteArrayInputStream(bCert);
cert = (X509Certificate) cf.generateCertificate(certAuxIs);
certs.add(cert);
}
_cached = true;
return sRes;
}
public Certificate getCertificate(String alias) throws CertificateException, Exception
{
int i = 0;
if (!_cached)
{
getCertificateAliases();
}
for (Enumeration e = aliases.elements(); e.hasMoreElements(); i++)
{
if (alias.equals(e.nextElement()))
{
return certs.get(i);
}
}
return null;
}
public PrivateKey getPrivateKey(String alias) throws Exception
{
HexEncoder hex = new HexEncoder();
// Base64 b64= new Base64();
if (!_initialized || !_isAuth)
{
throw new Exception("UninitializedClauerOrUnauthenticated");
}
byte[] block = new byte[10240];
int nblock = clRunTime.readFirstTypeBlock(this.TYPE_PEM_PRIVATE_KEY, block);
// System.out.println("alias = " + alias);
while (nblock != -1)
{
ByteArrayOutputStream bOs = new ByteArrayOutputStream();
hex.encode(block, 8 + 4 + 1, 20, bOs);
String id = bOs.toString();
if (id.equals(alias))
{
ByteArrayInputStream keyIs = new ByteArrayInputStream(block);
DataInputStream dis = new DataInputStream(keyIs);
/* Take out the header */
dis.readInt();
dis.readInt();
dis.read();
int tam = Integer.reverseBytes(dis.readInt());
/* Take out irrelevant info */
for (int i = 0; i < 20; i++)
{
dis.read();
}
/* Read certificate information */
byte[] bkey = new byte[tam];
dis.read(bkey, 0, tam);
// KeyFactory rSAKeyFactory = KeyFactory.getInstance("RSA");
// String bk= new String(bkey);
// System.out.println("KEY: " + bk );
Reader fRd = new BufferedReader(new InputStreamReader(
new ByteArrayInputStream(bkey)));
_installBCprovider();
PEMReader pemRd = new PEMReader(fRd, null);
Object o;
o = pemRd.readObject();
if (o instanceof KeyPair)
{
KeyPair pair = (KeyPair) o;
// System.out.println(pair.getPublic());
PrivateKey p = pair.getPrivate();
return p;
}
}
nblock = clRunTime.readNextTypeBlock(this.TYPE_PEM_PRIVATE_KEY, block, nblock);
}
return null;
}
}