package es.uji.security.keystore;
import java.security.Provider;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateParsingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Iterator;
import es.uji.security.crypto.SupportedKeystore;
import es.uji.security.keystore.IKeyStore;
/**
* _keyUsage is a boolean array where positions are:
*
* digitalSignature a[0]; nonRepudiation a[1]; keyEncipherment a[2]; dataEncipherment a[3];
* keyAgreement a[4]; keycertSign a[5]; CRLSign a[6]; encipherOnly a[7]; decipherOnly a[8];
*/
public class X509CertificateHandler
{
private String _SubjectDN;
private String _SubjectCN;
private String _IssuerDN;
private String _IssuerOrganization;
private String _alias;
private SupportedKeystore _storeName;
private String _tokenName;
private Provider _provider;
private List<String> _extKeyUsage;
private X509Certificate _xcer = null;
private IKeyStore _iksh = null;
boolean[] _keyUsage;
boolean _emailProtection = false;
private String[] _keyUsageStr = { "digitalSignature", "nonRepudiation", "keyEncipherment",
"dataEncipherment", "keyAgreement", "keycertSign", "CRLSign", "encipherOnly",
"decipherOnly", };
public X509CertificateHandler(X509Certificate xcer, String alias, IKeyStore iksh)
throws CertificateParsingException
{
_iksh = iksh;
initialize(xcer, alias, _iksh.getProvider(), _iksh.getName(), _iksh.getTokenName());
}
public X509CertificateHandler(X509Certificate xcer, String alias, Provider provider,
SupportedKeystore storeName, String tokenName) throws CertificateParsingException
{
_iksh = null;
initialize(xcer, alias, provider, storeName, tokenName);
}
public void initialize(X509Certificate xcer, String alias, Provider provider, SupportedKeystore storeName,
String tokenName) throws CertificateParsingException
{
_SubjectDN = xcer.getSubjectDN().getName();
_IssuerDN = xcer.getIssuerDN().getName();
_keyUsage = xcer.getKeyUsage();
_extKeyUsage = xcer.getExtendedKeyUsage();
_alias = alias;
_provider = provider;
_storeName = storeName;
_xcer = xcer;
_tokenName = tokenName;
extractIssuerOrganizationFromDN();
extractSubjectFromDN();
}
private void extractSubjectFromDN()
{
int auxIdx = _SubjectDN.indexOf("CN=");
if (auxIdx <= -1) {
_SubjectCN = "";
return;
}
String auxStr = _SubjectDN.substring(auxIdx);
auxStr = auxStr.replaceFirst("CN=", "");
if (auxStr.indexOf("=") > -1)
{
auxStr = auxStr.substring(0, auxStr.indexOf("=") - 3);
}
auxStr = auxStr.replace('\"', ' ');
auxStr = auxStr.trim();
auxStr = auxStr.trim();
if (auxStr.charAt(auxStr.length() - 1) == ',')
{
auxStr = auxStr.substring(0, auxStr.length() - 2);
}
_SubjectCN = auxStr;
if (_SubjectCN == null ||_SubjectCN.isEmpty())
{
_SubjectCN = extractDNField("OU", _SubjectDN);
}
}
private void extractIssuerOrganizationFromDN()
{
String auxStr = "Unknown";
int auxIdx = _IssuerDN.indexOf("O=");
if (auxIdx != -1)
{
auxStr = _IssuerDN.substring(auxIdx);
auxStr = auxStr.replaceFirst("O=", "");
}
else
{
auxIdx = _IssuerDN.indexOf("O =");
if (auxIdx != -1)
{
auxStr = _IssuerDN.substring(auxIdx);
auxStr = auxStr.replaceFirst("O =", "");
}
}
if (auxStr.indexOf("=") > -1)
{
auxStr = auxStr.substring(0, auxStr.indexOf(","));
}
auxStr = auxStr.replace('\"', ' ');
auxStr = auxStr.trim();
_IssuerOrganization = auxStr;
}
private String join(java.util.Collection collection, String separator) {
if (collection == null) return "";
Iterator iterator = collection.iterator();
if (iterator == null)
{
return null;
}
if (!iterator.hasNext())
{
return "";
}
Object first = iterator.next();
if (!iterator.hasNext())
{
return (first == null) ? "" : first.toString();
}
StringBuffer buf = new StringBuffer(256);
if (first != null)
{
buf.append(first);
}
while (iterator.hasNext())
{
if (separator != null)
{
buf.append(separator);
}
Object obj = iterator.next();
if (obj != null) {
buf.append(obj);
}
}
return buf.toString();
}
private String extractDNField(String fieldToExtract, String dn)
{
if (fieldToExtract == null || dn == null) return "";
List<String> values = new ArrayList<String>();
for (String field : dn.split(","))
{
String fieldType = field.trim().split("=")[0];
String fieldValue = field.trim().split("=")[1];
if (fieldToExtract.equalsIgnoreCase(fieldType))
{
values.add(fieldValue);
}
}
return join(values, " - ");
}
public X509Certificate getCertificate()
{
return _xcer;
}
public String getAlias()
{
try
{
if (_iksh != null)
return _iksh.getAliasFromCertificate(_xcer);
}
catch (Exception e)
{
}
return null;
}
public String getIssuerOrganization()
{
return _IssuerOrganization;
}
public String getExtendedInfo()
{
String auxStr = "\n Emitido por: " + _IssuerOrganization + "\n";
auxStr += " Pertenece a: " + _SubjectCN + "\n";
auxStr += " Uso de la llave: ";
// System.out.println("SubjCN: " +auxStr);
if (_keyUsage != null)
{
for (int i = 0; i < _keyUsage.length; i++)
{
if (_keyUsage[i])
{
auxStr += _keyUsageStr[i] + ", ";
}
}
}
if (_extKeyUsage != null)
{
for (String u : _extKeyUsage)
{
auxStr += u + ", ";
}
}
auxStr = auxStr.substring(0, auxStr.length() - 2);
auxStr += "\n";
return auxStr;
}
public String getKeyUsage()
{
String auxStr = "";
// System.out.println("Parseando keyUsage...");
if (_keyUsage != null)
{
for (int i = 0; i < _keyUsage.length; i++)
{
if (_keyUsage[i])
{
auxStr += _keyUsageStr[i] + ", ";
// System.out.println("pillado usage: " + auxStr);
}
}
auxStr = auxStr.substring(0, auxStr.length() - 2);
}
if (_extKeyUsage != null)
{
for (String u : _extKeyUsage)
{
if (u.equals("1.3.6.1.5.5.7.3.4"))
{
_emailProtection = true;
}
}
}
if (_keyUsage[2]) // keyEncipherment
_emailProtection = true;
return auxStr;
}
public boolean isEmailProtectionCertificate()
{
return _emailProtection;
}
public boolean isDigitalSignatureCertificate()
{
if (_keyUsage != null)
return _keyUsage[0];
else
return false;
}
public boolean isNonRepudiationCertificate()
{
if (_keyUsage != null)
return _keyUsage[1];
else
return false;
}
public boolean isPKCS11Provider()
{
System.out.println("STORE: " + getStoreName());
if (getStoreName().equals(SupportedKeystore.PKCS11))
{
return true;
}
else
{
return false;
}
}
/*
* Kept out for compatibility reasons
*/
public boolean isClauerProvider()
{
if (getStoreName().equals(SupportedKeystore.CLAUER))
{
return true;
}
else
{
return false;
}
}
public IKeyStore getKeyStore()
{
return _iksh;
}
public SupportedKeystore getStoreName()
{
return _storeName;
}
public String getTokenName()
{
return _tokenName;
}
public String toString()
{
String kuAux = getKeyUsage();
if (kuAux.equals(""))
return _SubjectCN;
else
return _SubjectCN + " (" + getKeyUsage() + ")";
}
}