private void parse(InputStream encoded) throws Exception
{
DERReader der = new DERReader(encoded);
// Certificate ::= SEQUENCE {
DERValue cert = der.read();
Logger logger = logger();
logger.log (Component.X509, "start Certificate len == {0}",
Integer.valueOf(cert.getLength()));
this.encoded = cert.getEncoded();
if (!cert.isConstructed())
{
throw new IOException("malformed Certificate");
}
// TBSCertificate ::= SEQUENCE {
DERValue tbsCert = der.read();
if (tbsCert.getValue() != DER.CONSTRUCTED_VALUE)
{
throw new IOException("malformed TBSCertificate");
}
tbsCertBytes = tbsCert.getEncoded();
logger.log (Component.X509, "start TBSCertificate len == {0}",
Integer.valueOf(tbsCert.getLength()));
// Version ::= INTEGER [0] { v1(0), v2(1), v3(2) }
DERValue val = der.read();
if (val.getTagClass() == DER.CONTEXT && val.getTag() == 0)
{
version = ((BigInteger) der.read().getValue()).intValue() + 1;
val = der.read();
}
else
{
version = 1;
}
logger.log (Component.X509, "read version == {0}",
Integer.valueOf(version));
// SerialNumber ::= INTEGER
serialNo = (BigInteger) val.getValue();
logger.log (Component.X509, "read serial number == {0}", serialNo);
// AlgorithmIdentifier ::= SEQUENCE {
val = der.read();
if (!val.isConstructed())
{
throw new IOException("malformed AlgorithmIdentifier");
}
int certAlgLen = val.getLength();
logger.log (Component.X509, "start AlgorithmIdentifier len == {0}",
Integer.valueOf(certAlgLen));
val = der.read();
// algorithm OBJECT IDENTIFIER,
algId = (OID) val.getValue();
logger.log (Component.X509, "read algorithm ID == {0}", algId);
// parameters ANY DEFINED BY algorithm OPTIONAL }
if (certAlgLen > val.getEncodedLength())
{
val = der.read();
if (val == null)
{
algVal = null;
}
else
{
algVal = val.getEncoded();
if (val.isConstructed())
encoded.skip(val.getLength());
}
logger.log (Component.X509, "read algorithm parameters == {0}", algVal);
}
// issuer Name,
val = der.read();
issuer = new X500DistinguishedName(val.getEncoded());
der.skip(val.getLength());
logger.log (Component.X509, "read issuer == {0}", issuer);
// Validity ::= SEQUENCE {
// notBefore Time,
// notAfter Time }
if (!der.read().isConstructed())
{
throw new IOException("malformed Validity");
}
notBefore = (Date) der.read().getValue();
logger.log (Component.X509, "read notBefore == {0}", notBefore);
notAfter = (Date) der.read().getValue();
logger.log (Component.X509, "read notAfter == {0}", notAfter);
// subject Name,
val = der.read();
subject = new X500DistinguishedName(val.getEncoded());
der.skip(val.getLength());
logger.log (Component.X509, "read subject == {0}", subject);
// SubjectPublicKeyInfo ::= SEQUENCE {
// algorithm AlgorithmIdentifier,
// subjectPublicKey BIT STRING }
DERValue spki = der.read();
if (!spki.isConstructed())
{
throw new IOException("malformed SubjectPublicKeyInfo");
}
KeyFactory spkFac = KeyFactory.getInstance("X.509");
subjectKey = spkFac.generatePublic(new X509EncodedKeySpec(spki.getEncoded()));
der.skip(spki.getLength());
logger.log (Component.X509, "read subjectPublicKey == {0}", subjectKey);
val = der.read();
if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 1)
{
byte[] b = (byte[]) val.getValue();
issuerUniqueId = new BitString(b, 1, b.length-1, b[0] & 0xFF);
logger.log (Component.X509, "read issuerUniqueId == {0}", issuerUniqueId);
val = der.read();
}
if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 2)
{
byte[] b = (byte[]) val.getValue();
subjectUniqueId = new BitString(b, 1, b.length-1, b[0] & 0xFF);
logger.log (Component.X509, "read subjectUniqueId == {0}", subjectUniqueId);
val = der.read();
}
if (version >= 3 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 3)
{
val = der.read();
logger.log (Component.X509, "start Extensions len == {0}",
Integer.valueOf(val.getLength()));
int len = 0;
while (len < val.getLength())
{
DERValue ext = der.read();
logger.log (Component.X509, "start extension len == {0}",
Integer.valueOf(ext.getLength()));
Extension e = new Extension(ext.getEncoded());
extensions.put(e.getOid(), e);
der.skip(ext.getLength());
len += ext.getEncodedLength();
logger.log (Component.X509, "read extension {0} == {1}",
new Object[] { e.getOid (), e });
logger.log (Component.X509, "count == {0}", Integer.valueOf(len));
}