package gnu.java.security.x509;
import java.io.IOException;
import java.math.BigInteger;
import java.security.cert.CRLException;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import gnu.java.security.OID;
import gnu.java.security.der.*;
import gnu.java.security.x509.ext.*;
class X509CRLEntry extends java.security.cert.X509CRLEntry
implements GnuPKIExtension
{
private static final boolean DEBUG = false;
private static void debug(String msg)
{
if (DEBUG)
{
System.err.print(">> X509CRLEntry: ");
System.err.println(msg);
}
}
private byte[] encoded;
private BigInteger serialNo;
private Date revocationDate;
private HashMap extensions;
X509CRLEntry(int version, DERReader encoded)
throws CRLException, IOException
{
super();
extensions = new HashMap();
try
{
parse(version, encoded);
}
catch (IOException ioe)
{
throw ioe;
}
catch (Exception x)
{
throw new CRLException(x.toString());
}
}
public boolean equals(Object o)
{
if (!(o instanceof X509CRLEntry))
return false;
return ((X509CRLEntry) o).getSerialNumber().equals(serialNo) &&
((X509CRLEntry) o).getRevocationDate().equals(revocationDate);
}
public int hashCode()
{
return serialNo.hashCode();
}
public byte[] getEncoded() throws CRLException
{
return (byte[]) encoded.clone();
}
public BigInteger getSerialNumber()
{
return serialNo;
}
public Date getRevocationDate()
{
return (Date) revocationDate.clone();
}
public boolean hasExtensions()
{
return ! extensions.isEmpty();
}
public String toString()
{
return "X509CRLEntry serial=" + serialNo + " revocation date="
+ revocationDate + " ext=" + extensions;
}
public boolean hasUnsupportedCriticalExtension()
{
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
{
Extension e = (Extension) it.next();
if (e.isCritical() && !e.isSupported())
return true;
}
return false;
}
public Set getCriticalExtensionOIDs()
{
HashSet s = new HashSet();
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
{
Extension e = (Extension) it.next();
if (e.isCritical())
s.add(e.getOid().toString());
}
return Collections.unmodifiableSet(s);
}
public Set getNonCriticalExtensionOIDs()
{
HashSet s = new HashSet();
for (Iterator it = extensions.values().iterator(); it.hasNext(); )
{
Extension e = (Extension) it.next();
if (!e.isCritical())
s.add(e.getOid().toString());
}
return Collections.unmodifiableSet(s);
}
public byte[] getExtensionValue(String oid)
{
Extension e = getExtension(new OID(oid));
if (e != null)
{
return e.getValue().getEncoded();
}
return null;
}
public Extension getExtension(OID oid)
{
return (Extension) extensions.get(oid);
}
public Collection getExtensions()
{
return extensions.values();
}
private void parse(int version, DERReader der) throws Exception
{
DERValue entry = der.read();
debug("start CRL entry len == " + entry.getLength());
if (!entry.isConstructed())
throw new IOException("malformed revokedCertificate");
encoded = entry.getEncoded();
int len = 0;
debug("encoded entry:\n" + Util.hexDump(encoded, ">>>> "));
DERValue val = der.read();
serialNo = (BigInteger) val.getValue();
len += val.getEncodedLength();
debug("userCertificate == " + serialNo + " current count == " + len);
val = der.read();
revocationDate = (Date) val.getValue();
len += val.getEncodedLength();
debug("revocationDate == " + revocationDate + " current count == " + len);
if (len < entry.getLength())
{
if (version < 2)
throw new IOException("extra data in CRL entry");
DERValue exts = der.read();
if (!exts.isConstructed())
throw new IOException("malformed Extensions");
debug("start Extensions len == " + exts.getLength());
len = 0;
while (len < exts.getLength())
{
val = der.read();
if (!val.isConstructed())
throw new IOException("malformed Extension");
debug("start Extension len == " + val.getLength());
Extension e = new Extension(val.getEncoded());
extensions.put(e.getOid(), e);
der.skip(val.getLength());
len += val.getEncodedLength();
debug("current count == " + len);
}
}
}
}