--- /dev/null
+package org.bouncycastle.asn1;
+
+import java.io.*;
+import java.util.*;
+
+public abstract class ASN1OctetString
+ extends DERObject
+{
+ byte[] string;
+
+ /**
+ * return an Octet String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want.
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static ASN1OctetString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
+ /**
+ * return an Octet String from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static ASN1OctetString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof ASN1OctetString)
+ {
+ return (ASN1OctetString)obj;
+ }
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ return getInstance(((ASN1TaggedObject)obj).getObject());
+ }
+
+ if (obj instanceof ASN1Sequence)
+ {
+ Vector v = new Vector();
+ Enumeration e = ((ASN1Sequence)obj).getObjects();
+
+ while (e.hasMoreElements())
+ {
+ v.addElement(e.nextElement());
+ }
+
+ return new BERConstructedOctetString(v);
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * @param string the octets making up the octet string.
+ */
+ public ASN1OctetString(
+ byte[] string)
+ {
+ this.string = string;
+ }
+
+ public ASN1OctetString(
+ DEREncodable obj)
+ {
+ try
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ DEROutputStream dOut = new DEROutputStream(bOut);
+
+ dOut.writeObject(obj);
+ dOut.close();
+
+ this.string = bOut.toByteArray();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("Error processing object : " + e.toString());
+ }
+ }
+
+ public byte[] getOctets()
+ {
+ return string;
+ }
+
+ public int hashCode()
+ {
+ byte[] b = this.getOctets();
+ int value = 0;
+
+ for (int i = 0; i != b.length; i++)
+ {
+ value ^= (b[i] & 0xff) << (i % 4);
+ }
+
+ return value;
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (o == null || !(o instanceof DEROctetString))
+ {
+ return false;
+ }
+
+ DEROctetString other = (DEROctetString)o;
+
+ byte[] b1 = other.getOctets();
+ byte[] b2 = this.getOctets();
+
+ if (b1.length != b2.length)
+ {
+ return false;
+ }
+
+ for (int i = 0; i != b1.length; i++)
+ {
+ if (b1[i] != b2[i])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ abstract void encode(DEROutputStream out)
+ throws IOException;
+}
--- /dev/null
+package org.bouncycastle.asn1;
+
+import java.io.*;
+
+public class ASN1OutputStream
+ extends DEROutputStream
+{
+ public ASN1OutputStream(
+ OutputStream os)
+ {
+ super(os);
+ }
+
+ public void writeObject(
+ Object obj)
+ throws IOException
+ {
+ if (obj == null)
+ {
+ writeNull();
+ }
+ else if (obj instanceof DERObject)
+ {
+ ((DERObject)obj).encode(this);
+ }
+ else if (obj instanceof DEREncodable)
+ {
+ ((DEREncodable)obj).getDERObject().encode(this);
+ }
+ else
+ {
+ throw new IOException("object not ASN1Encodable");
+ }
+ }
+}
--- /dev/null
+package org.bouncycastle.asn1;
+
+import java.io.*;
+import java.util.*;
+
+public abstract class ASN1Sequence
+ extends DERObject
+{
+ private Vector seq = new Vector();
+
+ /**
+ * return an ASN1Sequence from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static ASN1Sequence getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof ASN1Sequence)
+ {
+ return (ASN1Sequence)obj;
+ }
+
+ throw new IllegalArgumentException("unknown object in getInstance");
+ }
+
+ /**
+ * Return an ASN1 sequence from a tagged object. There is a special
+ * case here, if an object appears to have been explicitly tagged on
+ * reading but we were expecting it to be implictly tagged in the
+ * normal course of events it indicates that we lost the surrounding
+ * sequence - so we need to add it back (this will happen if the tagged
+ * object is a sequence that contains other sequences). If you are
+ * dealing with implicitly tagged sequences you really <b>should</b>
+ * be using this method.
+ *
+ * @param obj the tagged object.
+ * @param explicit true if the object is meant to be explicitly tagged,
+ * false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static ASN1Sequence getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ if (explicit)
+ {
+ if (!obj.isExplicit())
+ {
+ throw new IllegalArgumentException("object implicit - explicit expected.");
+ }
+
+ return (ASN1Sequence)obj.getObject();
+ }
+ else
+ {
+ //
+ // constructed object which appears to be explicitly tagged
+ // when it should be implicit means we have to add the
+ // surrounding sequence.
+ //
+ if (obj.isExplicit())
+ {
+ ASN1Sequence seq;
+
+ if (obj instanceof BERTaggedObject)
+ {
+ seq = new BERConstructedSequence();
+ }
+ else
+ {
+ seq = new DERConstructedSequence();
+ }
+
+ seq.addObject(obj.getObject());
+
+ return seq;
+ }
+ else
+ {
+ ASN1Sequence seq;
+
+ if (obj.getObject() instanceof ASN1Sequence)
+ {
+ return (ASN1Sequence)obj.getObject();
+ }
+ }
+ }
+
+ throw new IllegalArgumentException(
+ "unknown object in getInstanceFromTagged");
+ }
+
+ public Enumeration getObjects()
+ {
+ return seq.elements();
+ }
+
+ /**
+ * return the object at the sequence postion indicated by index.
+ *
+ * @param the sequence number (starting at zero) of the object
+ * @return the object at the sequence postion indicated by index.
+ */
+ public DEREncodable getObjectAt(
+ int index)
+ {
+ return (DEREncodable)seq.elementAt(index);
+ }
+
+ /**
+ * return the number of objects in this sequence.
+ *
+ * @return the number of objects in this sequence.
+ */
+ public int size()
+ {
+ return seq.size();
+ }
+
+ public int hashCode()
+ {
+ Enumeration e = this.getObjects();
+ int hashCode = 0;
+
+ while (e.hasMoreElements())
+ {
+ hashCode ^= e.nextElement().hashCode();
+ }
+
+ return hashCode;
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (o == null || !(o instanceof ASN1Sequence))
+ {
+ return false;
+ }
+
+ ASN1Sequence other = (ASN1Sequence)o;
+
+ if (this.size() != other.size())
+ {
+ return false;
+ }
+
+ Enumeration s1 = this.getObjects();
+ Enumeration s2 = other.getObjects();
+
+ while (s1.hasMoreElements())
+ {
+ if (!s1.nextElement().equals(s2.nextElement()))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ protected void addObject(
+ DEREncodable obj)
+ {
+ seq.addElement(obj);
+ }
+
+ abstract void encode(DEROutputStream out)
+ throws IOException;
+}
--- /dev/null
+package org.bouncycastle.asn1;
+
+import java.io.*;
+import java.util.*;
+
+abstract public class ASN1Set
+ extends DERObject
+{
+ protected Vector set = new Vector();
+
+ /**
+ * return an ASN1Set from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static ASN1Set getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof ASN1Set)
+ {
+ return (ASN1Set)obj;
+ }
+
+ throw new IllegalArgumentException("unknown object in getInstance");
+ }
+
+ /**
+ * Return an ASN1 set from a tagged object. There is a special
+ * case here, if an object appears to have been explicitly tagged on
+ * reading but we were expecting it to be implictly tagged in the
+ * normal course of events it indicates that we lost the surrounding
+ * set - so we need to add it back (this will happen if the tagged
+ * object is a sequence that contains other sequences). If you are
+ * dealing with implicitly tagged sets you really <b>should</b>
+ * be using this method.
+ *
+ * @param obj the tagged object.
+ * @param explicit true if the object is meant to be explicitly tagged
+ * false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static ASN1Set getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ if (explicit)
+ {
+ if (!obj.isExplicit())
+ {
+ throw new IllegalArgumentException("object implicit - explicit expected.");
+ }
+
+ return (ASN1Set)obj.getObject();
+ }
+ else
+ {
+ //
+ // constructed object which appears to be explicitly tagged
+ // and it's really implicit means we have to add the
+ // surrounding sequence.
+ //
+ if (obj.isExplicit())
+ {
+ ASN1Set set = new DERSet(obj.getObject());
+
+ return set;
+ }
+ else
+ {
+ //
+ // in this case the parser returns a sequence, convert it
+ // into a set.
+ //
+ DEREncodableVector v = new DEREncodableVector();
+
+ if (obj.getObject() instanceof ASN1Sequence)
+ {
+ ASN1Sequence s = (ASN1Sequence)obj.getObject();
+ Enumeration e = s.getObjects();
+
+ while (e.hasMoreElements())
+ {
+ v.add((DEREncodable)e.nextElement());
+ }
+
+ return new DERSet(v);
+ }
+ }
+ }
+
+ throw new IllegalArgumentException(
+ "unknown object in getInstanceFromTagged");
+ }
+
+ public ASN1Set()
+ {
+ }
+
+ public Enumeration getObjects()
+ {
+ return set.elements();
+ }
+
+ /**
+ * return the object at the set postion indicated by index.
+ *
+ * @param the set number (starting at zero) of the object
+ * @return the object at the set postion indicated by index.
+ */
+ public DEREncodable getObjectAt(
+ int index)
+ {
+ return (DEREncodable)set.elementAt(index);
+ }
+
+ /**
+ * return the number of objects in this set.
+ *
+ * @return the number of objects in this set.
+ */
+ public int size()
+ {
+ return set.size();
+ }
+
+ public int hashCode()
+ {
+ Enumeration e = this.getObjects();
+ int hashCode = 0;
+
+ while (e.hasMoreElements())
+ {
+ hashCode ^= e.nextElement().hashCode();
+ }
+
+ return hashCode;
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (o == null || !(o instanceof ASN1Set))
+ {
+ return false;
+ }
+
+ ASN1Set other = (ASN1Set)o;
+
+ if (this.size() != other.size())
+ {
+ return false;
+ }
+
+ Enumeration s1 = this.getObjects();
+ Enumeration s2 = other.getObjects();
+
+ while (s1.hasMoreElements())
+ {
+ if (!s1.nextElement().equals(s2.nextElement()))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ protected void addObject(
+ DEREncodable obj)
+ {
+ set.addElement(obj);
+ }
+
+ abstract void encode(DEROutputStream out)
+ throws IOException;
+}
--- /dev/null
+package org.bouncycastle.asn1;
+
+import java.io.*;
+
+/**
+ * ASN.1 TaggedObject - in ASN.1 nottation this is any object proceeded by
+ * a [n] where n is some number - these are assume to follow the construction
+ * rules (as with sequences).
+ */
+public abstract class ASN1TaggedObject
+ extends DERObject
+{
+ int tagNo;
+ boolean empty = false;
+ boolean explicit = true;
+ DEREncodable obj = null;
+
+ /**
+ * @param tagNo the tag number for this object.
+ * @param obj the tagged object.
+ */
+ public ASN1TaggedObject(
+ int tagNo,
+ DEREncodable obj)
+ {
+ this.explicit = true;
+ this.tagNo = tagNo;
+ this.obj = obj;
+ }
+
+ /**
+ * @param explicit true if the object is explicitly tagged.
+ * @param tagNo the tag number for this object.
+ * @param obj the tagged object.
+ */
+ public ASN1TaggedObject(
+ boolean explicit,
+ int tagNo,
+ DEREncodable obj)
+ {
+ this.explicit = explicit;
+ this.tagNo = tagNo;
+ this.obj = obj;
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (o == null || !(o instanceof ASN1TaggedObject))
+ {
+ return false;
+ }
+
+ ASN1TaggedObject other = (ASN1TaggedObject)o;
+
+ if(tagNo != other.tagNo || empty != other.empty || explicit != other.explicit)
+ {
+ return false;
+ }
+
+ if(obj == null)
+ {
+ if(other.obj != null)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if(!(obj.equals(other.obj)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public int getTagNo()
+ {
+ return tagNo;
+ }
+
+ /**
+ * return whether or not the object may be explicitly tagged.
+ * <p>
+ * Note: if the object has been read from an input stream, the only
+ * time you can be sure if isExplicit is returning the true state of
+ * affairs is if it returns false. An implicitly tagged object may appear
+ * to be explicitly tagged, so you need to understand the context under
+ * which the reading was done as well, see getObject below.
+ */
+ public boolean isExplicit()
+ {
+ return explicit;
+ }
+
+ public boolean isEmpty()
+ {
+ return empty;
+ }
+
+ /**
+ * return whatever was following the tag.
+ * <p>
+ * Note: tagged objects are generally context dependent if you're
+ * trying to extract a tagged object you should be going via the
+ * appropriate getInstance method.
+ */
+ public DERObject getObject()
+ {
+ if (obj != null)
+ {
+ return obj.getDERObject();
+ }
+
+ return null;
+ }
+
+ abstract void encode(DEROutputStream out)
+ throws IOException;
+}
return string;
}
- public Vector getDEROctets()
+ /**
+ * return the DER octets that make up this string.
+ */
+ public Enumeration getObjects()
{
if (octs == null)
{
octs = generateOcts();
}
- return octs;
+ return octs.elements();
}
private Vector generateOcts()
int end = 0;
Vector vec = new Vector();
- while (end < string.length)
+ while ((end + 1) < string.length)
{
- if ((end + 1) < string.length)
+ if (string[end] == 0 && string[end + 1] == 0)
{
- if (string[end] == 0 && string[end + 1] == 0)
- {
- byte[] nStr = new byte[end - start + 1];
+ byte[] nStr = new byte[end - start + 1];
- for (int i = 0; i != nStr.length; i++)
- {
- nStr[i] = string[start + i];
- }
-
- vec.addElement(new DEROctetString(nStr));
- start = end + 1;
+ for (int i = 0; i != nStr.length; i++)
+ {
+ nStr[i] = string[start + i];
}
+
+ vec.addElement(new DEROctetString(nStr));
+ start = end + 1;
}
end++;
}
- byte[] nStr = new byte[end - start];
+ byte[] nStr = new byte[string.length - start];
for (int i = 0; i != nStr.length; i++)
{
nStr[i] = string[start + i];
DEROutputStream out)
throws IOException
{
- if (out instanceof BEROutputStream)
- {
+ if (out instanceof ASN1OutputStream || out instanceof BEROutputStream)
+ {
out.write(CONSTRUCTED | OCTET_STRING);
out.write(0x80);
out.write(0x00);
out.write(0x00);
- }
- else
- {
- super.encode(out);
- }
+ }
+ else
+ {
+ super.encode(out);
+ }
}
}
extends DERConstructedSequence
{
/*
- * A note on the implementation:
- * <p>
- * As DER requires the constructed, definite-length model to
- * be used for structured types, this varies slightly from the
- * ASN.1 descriptions given. Rather than just outputing SEQUENCE,
- * we also have to specify CONSTRUCTED, and the objects length.
*/
void encode(
DEROutputStream out)
throws IOException
{
- if (out instanceof BEROutputStream)
+ if (out instanceof ASN1OutputStream || out instanceof BEROutputStream)
{
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- BEROutputStream dOut = new BEROutputStream(bOut);
- Enumeration e = getObjects();
-
+ out.write(SEQUENCE | CONSTRUCTED);
+ out.write(0x80);
+
+ Enumeration e = getObjects();
while (e.hasMoreElements())
{
- Object obj = e.nextElement();
-
- dOut.writeObject(obj);
+ out.writeObject(e.nextElement());
}
-
- dOut.close();
-
- byte[] bytes = bOut.toByteArray();
-
- out.write(SEQUENCE | CONSTRUCTED);
- out.write(0x80);
- out.write(bytes);
+
out.write(0x00);
out.write(0x00);
}
return bOut.toByteArray();
}
- private BERConstructedOctetString buildConstructedOctetString(
- DEROctetString o1,
- DEROctetString o2)
+ private BERConstructedOctetString buildConstructedOctetString()
throws IOException
{
Vector octs = new Vector();
- if (o1 != null)
- {
- octs.addElement(o1);
- octs.addElement(o2);
- }
-
for (;;)
{
DERObject o = readObject();
if (length < 0) // indefinite length method
{
- byte[] bytes;
-
switch (tag)
{
case NULL:
}
return seq;
case OCTET_STRING | CONSTRUCTED:
- return buildConstructedOctetString(null, null);
- default:
- if ((tag & (TAGGED | CONSTRUCTED)) != 0)
- {
- // with tagged object tag number is bottom 4 bits
- BERTaggedObject tagObj = new BERTaggedObject(tag & 0x0f, readObject());
- DERObject o = readObject();
+ return buildConstructedOctetString();
+ case SET | CONSTRUCTED:
+ DEREncodableVector v = new DEREncodableVector();
+
+ for (;;)
+ {
+ DERObject obj = readObject();
- if (o == END_OF_STREAM)
- {
- return tagObj;
- }
- else if (o instanceof DEROctetString
- && tagObj.getObject() instanceof DEROctetString)
+ if (obj == END_OF_STREAM)
{
- //
- // it's an implicit object - mark it as so...
- //
- tagObj = new BERTaggedObject(false, tag & 0x0f,
- buildConstructedOctetString((DEROctetString)tagObj.getObject(), (DEROctetString)o));
-
- return tagObj;
+ break;
}
- throw new IOException("truncated tagged object");
+ v.add(obj);
+ }
+ return new BERSet(v);
+ default:
+ //
+ // with tagged object tag number is bottom 5 bits
+ //
+ if ((tag & TAGGED) != 0)
+ {
+ if ((tag & 0x1f) == 0x1f)
+ {
+ throw new IOException("unsupported high tag encountered");
+ }
+
+ //
+ // simple type - implicit... return an octet string
+ //
+ if ((tag & CONSTRUCTED) == 0)
+ {
+ byte[] bytes = readIndefiniteLengthFully();
+
+ return new BERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes));
+ }
+
+ //
+ // either constructed or explicitly tagged
+ //
+ DERObject dObj = readObject();
+
+ if (dObj == END_OF_STREAM) // empty tag!
+ {
+ return new DERTaggedObject(tag & 0x1f);
+ }
+
+ DERObject next = readObject();
+
+ //
+ // explicitly tagged (probably!) - if it isn't we'd have to
+ // tell from the context
+ //
+ if (next == END_OF_STREAM)
+ {
+ return new BERTaggedObject(tag & 0x1f, dObj);
+ }
+
+ //
+ // another implicit object, we'll create a sequence...
+ //
+ seq = new BERConstructedSequence();
+
+ seq.addObject(dObj);
+
+ do
+ {
+ seq.addObject(next);
+ next = readObject();
+ }
+ while (next != END_OF_STREAM);
+
+ return new BERTaggedObject(false, tag & 0x1f, seq);
}
-
- bytes = readIndefiniteLengthFully();
- return buildObject(tag, bytes);
+ throw new IOException("unknown BER object encountered");
}
}
else
--- /dev/null
+package org.bouncycastle.asn1;
+
+import java.io.*;
+import java.util.*;
+
+public class BERSet
+ extends DERSet
+{
+ /**
+ * create an empty sequence
+ */
+ public BERSet()
+ {
+ }
+
+ /**
+ * create a set containing one object
+ */
+ public BERSet(
+ DEREncodable obj)
+ {
+ super(obj);
+ }
+
+ /**
+ * create a set containing a vector of objects.
+ */
+ public BERSet(
+ DEREncodableVector v)
+ {
+ super(v);
+ }
+
+ /*
+ */
+ void encode(
+ DEROutputStream out)
+ throws IOException
+ {
+ if (out instanceof ASN1OutputStream || out instanceof BEROutputStream)
+ {
+ out.write(SET | CONSTRUCTED);
+ out.write(0x80);
+
+ Enumeration e = getObjects();
+ while (e.hasMoreElements())
+ {
+ out.writeObject(e.nextElement());
+ }
+
+ out.write(0x00);
+ out.write(0x00);
+ }
+ else
+ {
+ super.encode(out);
+ }
+ }
+}
extends DERTaggedObject
{
/**
- * This creates an empty tagged object of tagNo (ie. zero length).
- *
* @param tagNo the tag number for this object.
+ * @param obj the tagged object.
*/
public BERTaggedObject(
- int tagNo)
+ int tagNo,
+ DEREncodable obj)
{
- super(tagNo);
+ super(tagNo, obj);
}
/**
+ * @param explicit true if an explicitly tagged object.
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
public BERTaggedObject(
- int tagNo,
- DERObject obj)
+ boolean explicit,
+ int tagNo,
+ DEREncodable obj)
{
- super(tagNo, obj);
+ super(explicit, tagNo, obj);
}
/**
- * @param explicit true if an explicitly tagged object.
- * @param tagNo the tag number for this object.
- * @param obj the tagged object.
+ * create an implicitly tagged object that contains a zero
+ * length sequence.
*/
public BERTaggedObject(
- boolean explicit,
- int tagNo,
- DERObject obj)
+ int tagNo)
{
- super(explicit, tagNo, obj);
+ super(false, tagNo, new BERConstructedSequence());
}
void encode(
DEROutputStream out)
throws IOException
{
- if (out instanceof BEROutputStream)
- {
+ if (out instanceof ASN1OutputStream || out instanceof BEROutputStream)
+ {
out.write(CONSTRUCTED | TAGGED | tagNo);
out.write(0x80);
- if (!empty)
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- BEROutputStream dOut = new BEROutputStream(bOut);
-
+ if (!empty)
+ {
if (!explicit)
{
if (obj instanceof BERConstructedOctetString)
{
- Vector octs = ((BERConstructedOctetString)obj).getDEROctets();
+ Enumeration e = ((BERConstructedOctetString)obj).getObjects();
+
+ while (e.hasMoreElements())
+ {
+ out.writeObject(e.nextElement());
+ }
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
+ Enumeration e = ((ASN1Sequence)obj).getObjects();
- for (int i = 0; i != octs.size(); i++)
+ while (e.hasMoreElements())
{
- dOut.writeObject(octs.elementAt(i));
+ out.writeObject(e.nextElement());
+ }
+ }
+ else if (obj instanceof ASN1Set)
+ {
+ Enumeration e = ((ASN1Set)obj).getObjects();
+
+ while (e.hasMoreElements())
+ {
+ out.writeObject(e.nextElement());
}
}
else
{
- dOut.writeObject(obj); // hmmm...
+ throw new RuntimeException("not implemented: " + obj.getClass().getName());
}
}
else
{
- dOut.writeObject(obj);
+ out.writeObject(obj);
}
-
- dOut.close();
-
- out.write(bOut.toByteArray());
- }
+ }
out.write(0x00);
out.write(0x00);
- }
- else
- {
- super.encode(out);
- }
+ }
+ else
+ {
+ super.encode(out);
+ }
}
}
String string;
/**
+ * return a BMP String from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static DERBMPString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERBMPString)
+ {
+ return (DERBMPString)obj;
+ }
+
+ if (obj instanceof ASN1OctetString)
+ {
+ return new DERBMPString(((ASN1OctetString)obj).getOctets());
+ }
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ return getInstance(((ASN1TaggedObject)obj).getObject());
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return a BMP String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static DERBMPString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
+
+ /**
* basic constructor - byte encoded string.
*/
public DERBMPString(
byte[] string)
{
- try
- {
- this.string = new String(string, "UnicodeBig");
- }
- catch (UnsupportedEncodingException e)
- {
- throw new RuntimeException(e.toString());
- }
+ char[] cs = new char[string.length / 2];
+
+ for (int i = 0; i != cs.length; i++)
+ {
+ cs[i] = (char)((string[2 * i] << 8) | (string[2 * i + 1] & 0xff));
+ }
+
+ this.string = new String(cs);
}
/**
return string;
}
+ public int hashCode()
+ {
+ return this.getString().hashCode();
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof DERBMPString))
+ {
+ return false;
+ }
+
+ DERPrintableString s = (DERPrintableString)o;
+
+ return this.getString().equals(s.getString());
+ }
+
void encode(
DEROutputStream out)
throws IOException
for (int i = 0; i != c.length; i++)
{
- b[2 * i] = (byte)((c[i] & 0xff00) >> 8);
+ b[2 * i] = (byte)(c[i] >> 8);
b[2 * i + 1] = (byte)c[i];
}
protected byte[] data;
protected int padBits;
+ /**
+ * return the correct number of pad bits for a bit string defined in
+ * a 16 bit constant
+ */
+ static protected int getPadBits(
+ int bitString)
+ {
+ int val;
+
+ if (bitString == 0)
+ {
+ return 7;
+ }
+
+ if (bitString > 255)
+ {
+ val = ((bitString >> 8) & 0xFF);
+ }
+ else
+ {
+ val = (bitString & 0xFF);
+ }
+
+ int bits = 1;
+
+ while (((val <<= 1) & 0xFF) != 0)
+ {
+ bits++;
+ }
+
+ return 8 - bits;
+ }
+
+ /**
+ * return the correct number of bytes for a bit string defined in
+ * a 16 bit constant
+ */
+ static protected byte[] getBytes(
+ int bitString)
+ {
+ if (bitString > 255)
+ {
+ byte[] bytes = new byte[2];
+
+ bytes[0] = (byte)(bitString & 0xFF);
+ bytes[1] = (byte)((bitString >> 8) & 0xFF);
+
+ return bytes;
+ }
+ else
+ {
+ byte[] bytes = new byte[1];
+
+ bytes[0] = (byte)(bitString & 0xFF);
+
+ return bytes;
+ }
+ }
+
+ /**
+ * return a Bit String from the passed in object
+ *
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static DERBitString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERBitString)
+ {
+ return (DERBitString)obj;
+ }
+
+ if (obj instanceof ASN1OctetString)
+ {
+ byte[] bytes = ((ASN1OctetString)obj).getOctets();
+ int padBits = bytes[0];
+ byte[] data = new byte[bytes.length - 1];
+
+ System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
+
+ return new DERBitString(data, padBits);
+ }
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ return getInstance(((ASN1TaggedObject)obj).getObject());
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return a Bit String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static DERBitString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
protected DERBitString(
byte data,
int padBits)
}
public DERBitString(
- DERObject obj)
+ DEREncodable obj)
{
try
{
}
}
- public DERBitString(
- DEREncodable obj)
- {
- this(obj.getDERObject());
- }
-
public byte[] getBytes()
{
return data;
out.writeEncoded(BIT_STRING, bytes);
}
+
+ public boolean equals(
+ Object o)
+ {
+ if (o == null || !(o instanceof DERBitString))
+ {
+ return false;
+ }
+
+ DERBitString other = (DERBitString)o;
+
+ if (data.length != other.data.length)
+ {
+ return false;
+ }
+
+ for (int i = 0; i != data.length; i++)
+ {
+ if (data[i] != other.data[i])
+ {
+ return false;
+ }
+ }
+
+ return (padBits == other.padBits);
+ }
}
{
byte value;
+ public static final DERBoolean FALSE = new DERBoolean(false);
+ public static final DERBoolean TRUE = new DERBoolean(true);
+
+ /**
+ * return a boolean from the passed in object.
+ *
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static DERBoolean getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERBoolean)
+ {
+ return (DERBoolean)obj;
+ }
+
+ if (obj instanceof ASN1OctetString)
+ {
+ return new DERBoolean(((ASN1OctetString)obj).getOctets());
+ }
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ return getInstance(((ASN1TaggedObject)obj).getObject());
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return a DERBoolean from the passed in boolean.
+ */
+ public static DERBoolean getInstance(
+ boolean value)
+ {
+ return (value ? TRUE : FALSE);
+ }
+
+ /**
+ * return a Boolean from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static DERBoolean getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
public DERBoolean(
byte[] value)
{
out.writeEncoded(BOOLEAN, bytes);
}
+
+ public boolean equals(
+ Object o)
+ {
+ if ((o == null) || !(o instanceof DERBoolean))
+ {
+ return false;
+ }
+
+ return (value == ((DERBoolean)o).value);
+ }
+
}
import java.util.*;
public class DERConstructedSequence
- extends DERObject
+ extends ASN1Sequence
{
- private Vector seq = new Vector();
-
- public DERConstructedSequence()
- {
- }
-
public void addObject(
DEREncodable obj)
{
- seq.addElement(obj);
- }
-
- public Enumeration getObjects()
- {
- return seq.elements();
- }
-
- /**
- * return the object at the sequence postion indicated by index.
- *
- * @param the sequence number (starting at zero) of the object
- * @return the object at the sequence postion indicated by index.
- */
- public Object getObjectAt(
- int index)
- {
- return seq.elementAt(index);
+ super.addObject(obj);
}
- /**
- * return the number of objects in this sequence.
- *
- * @return the number of objects in this sequence.
- */
public int getSize()
{
- return seq.size();
+ return size();
}
/*
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
DEROutputStream dOut = new DEROutputStream(bOut);
- Enumeration e = getObjects();
+ Enumeration e = this.getObjects();
while (e.hasMoreElements())
{
import java.util.*;
public class DERConstructedSet
- extends DERObject
+ extends ASN1Set
{
- private Vector set = new Vector();
-
public DERConstructedSet()
{
}
- public void addObject(
- DEREncodable obj)
+ /**
+ * @param obj - a single object that makes up the set.
+ */
+ public DERConstructedSet(
+ DEREncodable obj)
{
- set.addElement(obj);
+ this.addObject(obj);
}
- public Enumeration getObjects()
+ /**
+ * @param v - a vector of objects making up the set.
+ */
+ public DERConstructedSet(
+ DEREncodableVector v)
{
- return set.elements();
+ for (int i = 0; i != v.size(); i++)
+ {
+ this.addObject(v.get(i));
+ }
}
- /**
- * return the object at the set postion indicated by index.
- *
- * @param the set number (starting at zero) of the object
- * @return the object at the set postion indicated by index.
- */
- public Object getObjectAt(
- int index)
+ public void addObject(
+ DEREncodable obj)
{
- return set.elementAt(index);
+ super.addObject(obj);
}
- /**
- * return the number of objects in this set.
- *
- * @return the number of objects in this set.
- */
public int getSize()
{
- return set.size();
+ return size();
}
/*
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
DEROutputStream dOut = new DEROutputStream(bOut);
- Enumeration e = getObjects();
+ Enumeration e = this.getObjects();
while (e.hasMoreElements())
{
--- /dev/null
+package org.bouncycastle.asn1;
+
+import java.util.Vector;
+
+/**
+ * a general class for building up a vector of DER encodable objects
+ */
+public class DEREncodableVector
+{
+ private Vector v = new Vector();
+
+ public void add(
+ DEREncodable obj)
+ {
+ v.addElement(obj);
+ }
+
+ public DEREncodable get(
+ int i)
+ {
+ return (DEREncodable)v.elementAt(i);
+ }
+
+ public int size()
+ {
+ return v.size();
+ }
+}
--- /dev/null
+package org.bouncycastle.asn1;
+
+import java.io.*;
+import java.math.BigInteger;
+
+public class DEREnumerated
+ extends DERObject
+{
+ byte[] bytes;
+
+ /**
+ * return an integer from the passed in object
+ *
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static DEREnumerated getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DEREnumerated)
+ {
+ return (DEREnumerated)obj;
+ }
+
+ if (obj instanceof ASN1OctetString)
+ {
+ return new DEREnumerated(((ASN1OctetString)obj).getOctets());
+ }
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ return getInstance(((ASN1TaggedObject)obj).getObject());
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return an Enumerated from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static DEREnumerated getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
+ public DEREnumerated(
+ int value)
+ {
+ bytes = BigInteger.valueOf(value).toByteArray();
+ }
+
+ public DEREnumerated(
+ BigInteger value)
+ {
+ bytes = value.toByteArray();
+ }
+
+ public DEREnumerated(
+ byte[] bytes)
+ {
+ this.bytes = bytes;
+ }
+
+ public BigInteger getValue()
+ {
+ return new BigInteger(bytes);
+ }
+
+ void encode(
+ DEROutputStream out)
+ throws IOException
+ {
+ out.writeEncoded(ENUMERATED, bytes);
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (o == null || !(o instanceof DEREnumerated))
+ {
+ return false;
+ }
+
+ DEREnumerated other = (DEREnumerated)o;
+
+ if (bytes.length != other.bytes.length)
+ {
+ return false;
+ }
+
+ for (int i = 0; i != bytes.length; i++)
+ {
+ if (bytes[i] != other.bytes[i])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
--- /dev/null
+package org.bouncycastle.asn1;
+
+import java.io.*;
+import java.util.*;
+import java.io.*;
+import java.text.*;
+
+/**
+ * Generalized time object.
+ */
+public class DERGeneralizedTime
+ extends DERObject
+{
+ String time;
+
+ /**
+ * return a generalized time from the passed in object
+ *
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static DERGeneralizedTime getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERGeneralizedTime)
+ {
+ return (DERGeneralizedTime)obj;
+ }
+
+ if (obj instanceof ASN1OctetString)
+ {
+ return new DERGeneralizedTime(((ASN1OctetString)obj).getOctets());
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return a Generalized Time object from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static DERGeneralizedTime getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
+ /**
+ * The correct format for this is YYYYMMDDHHMMSSZ, or without the Z
+ * for local time, or Z+-HHMM on the end, for difference between local
+ * time and UTC time.
+ * <p>
+ *
+ * @param time the time string.
+ */
+ public DERGeneralizedTime(
+ String time)
+ {
+ this.time = time;
+ }
+
+ /**
+ * base constructer from a java.util.date object
+ */
+ public DERGeneralizedTime(
+ Date time)
+ {
+ SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
+
+ dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
+
+ this.time = dateF.format(time);
+ }
+
+ DERGeneralizedTime(
+ byte[] bytes)
+ {
+ //
+ // explicitly convert to characters
+ //
+ char[] dateC = new char[bytes.length];
+
+ for (int i = 0; i != dateC.length; i++)
+ {
+ dateC[i] = (char)(bytes[i] & 0xff);
+ }
+
+ this.time = new String(dateC);
+ }
+
+ /**
+ * return the time - always in the form of
+ * YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm).
+ * <p>
+ * Normally in a certificate we would expect "Z" rather than "GMT",
+ * however adding the "GMT" means we can just use:
+ * <pre>
+ * dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
+ * </pre>
+ * To read in the time and get a date which is compatible with our local
+ * time zone.
+ */
+ public String getTime()
+ {
+ //
+ // standardise the format.
+ //
+ if (time.length() == 15)
+ {
+ return time.substring(0, 14) + "GMT+00:00";
+ }
+ else if (time.length() == 17)
+ {
+ return time.substring(0, 14) + "GMT" + time.substring(15, 17) + ":" + time.substring(17, 19);
+ }
+
+ return time;
+ }
+
+ private byte[] getOctets()
+ {
+ char[] cs = time.toCharArray();
+ byte[] bs = new byte[cs.length];
+
+ for (int i = 0; i != cs.length; i++)
+ {
+ bs[i] = (byte)cs[i];
+ }
+
+ return bs;
+ }
+
+
+ void encode(
+ DEROutputStream out)
+ throws IOException
+ {
+ out.writeEncoded(GENERALIZED_TIME, this.getOctets());
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if ((o == null) || !(o instanceof DERGeneralizedTime))
+ {
+ return false;
+ }
+
+ return time.equals(((DERGeneralizedTime)o).time);
+ }
+}
String string;
/**
+ * return a IA5 string from the passed in object
+ *
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static DERIA5String getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERIA5String)
+ {
+ return (DERIA5String)obj;
+ }
+
+ if (obj instanceof ASN1OctetString)
+ {
+ return new DERIA5String(((ASN1OctetString)obj).getOctets());
+ }
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ return getInstance(((ASN1TaggedObject)obj).getObject());
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return an IA5 String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static DERIA5String getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
+ /**
* basic constructor - with bytes.
*/
public DERIA5String(
byte[] string)
{
- try
- {
- this.string = new String(string, "US-ASCII");
- }
- catch(UnsupportedEncodingException e)
+ char[] cs = new char[string.length];
+
+ for (int i = 0; i != cs.length; i++)
{
- throw new RuntimeException("PANIC: " + e);
+ cs[i] = (char)(string[i] & 0xff);
}
+
+ this.string = new String(cs);
}
/**
public byte[] getOctets()
{
- try
- {
- return string.getBytes("US-ASCII");
- }
- catch(UnsupportedEncodingException e)
+ char[] cs = string.toCharArray();
+ byte[] bs = new byte[cs.length];
+
+ for (int i = 0; i != cs.length; i++)
{
- throw new RuntimeException("PANIC: " + e);
+ bs[i] = (byte)cs[i];
}
+
+ return bs;
}
void encode(
{
out.writeEncoded(IA5_STRING, this.getOctets());
}
+
+ public int hashCode()
+ {
+ return this.getString().hashCode();
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof DERIA5String))
+ {
+ return false;
+ }
+
+ DERIA5String s = (DERIA5String)o;
+
+ return this.getString().equals(s.getString());
+ }
}
package org.bouncycastle.asn1;
import java.math.BigInteger;
-import java.io.*;
+import java.io.FilterInputStream;
+
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.EOFException;
+
public class DERInputStream
extends FilterInputStream implements DERTags
* from.
*/
protected DERObject buildObject(
- int tag,
+ int tag,
byte[] bytes)
throws IOException
{
bIn = new ByteArrayInputStream(bytes);
dIn = new BERInputStream(bIn);
- DERSet set = new DERSet(dIn.readObject());
+ DEREncodableVector v = new DEREncodableVector();
try
{
{
DERObject obj = dIn.readObject();
- set.addObject(obj);
+ v.add(obj);
}
}
catch (EOFException ex)
{
- return set;
+ return new DERConstructedSet(v);
}
case BOOLEAN:
return new DERBoolean(bytes);
case INTEGER:
return new DERInteger(bytes);
+ case ENUMERATED:
+ return new DEREnumerated(bytes);
case OBJECT_IDENTIFIER:
- int head = bytes[0] & 0xff;
- StringBuffer objId = new StringBuffer();
-
- objId.append(Integer.toString(head / 40));
- objId.append('.');
- objId.append(Integer.toString(head % 40));
-
- int value = 0;
-
- for (int i = 1; i != bytes.length; i++)
- {
- int b = bytes[i] & 0xff;
-
- value = value * 128 + (b & 0x7f);
- if ((b & 128) == 0) // end of number reached
- {
- objId.append('.');
- objId.append(Integer.toString(value));
- value = 0;
- }
- }
-
- return new DERObjectIdentifier(objId.toString());
+ return new DERObjectIdentifier(bytes);
case BIT_STRING:
int padBits = bytes[0];
byte[] data = new byte[bytes.length - 1];
System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
return new DERBitString(data, padBits);
+ case UTF8_STRING:
+ return new DERUTF8String(bytes);
case PRINTABLE_STRING:
return new DERPrintableString(bytes);
case IA5_STRING:
return new DERT61String(bytes);
case VISIBLE_STRING:
return new DERVisibleString(bytes);
+ case UNIVERSAL_STRING:
+ return new DERUniversalString(bytes);
case BMP_STRING:
return new DERBMPString(bytes);
case OCTET_STRING:
return new DEROctetString(bytes);
case UTC_TIME:
- return new DERUTCTime(new String(bytes));
+ return new DERUTCTime(bytes);
+ case GENERALIZED_TIME:
+ return new DERGeneralizedTime(bytes);
default:
//
- // with tagged object tag number is bottom 4 bits
+ // with tagged object tag number is bottom 5 bits
//
- if ((tag & (TAGGED | CONSTRUCTED)) != 0)
+ if ((tag & TAGGED) != 0)
{
+ if ((tag & 0x1f) == 0x1f)
+ {
+ throw new IOException("unsupported high tag encountered");
+ }
+
if (bytes.length == 0) // empty tag!
{
- return new DERTaggedObject(tag & 0x0f);
+ return new DERTaggedObject(false, tag & 0x1f, new DERConstructedSequence());
}
//
//
if ((tag & CONSTRUCTED) == 0)
{
- return new DERTaggedObject(false, tag & 0x0f, new DEROctetString(bytes));
+ return new DERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes));
}
bIn = new ByteArrayInputStream(bytes);
//
if (dIn.available() == 0)
{
- return new DERTaggedObject(tag & 0x0f, dObj);
+ return new DERTaggedObject(tag & 0x1f, dObj);
}
//
// ignore --
}
- return new DERTaggedObject(false, tag & 0x0f, seq);
+ return new DERTaggedObject(false, tag & 0x1f, seq);
}
return new DERUnknownTag(tag, bytes);
{
byte[] bytes;
+ /**
+ * return an integer from the passed in object
+ *
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static DERInteger getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERInteger)
+ {
+ return (DERInteger)obj;
+ }
+
+ if (obj instanceof ASN1OctetString)
+ {
+ return new DERInteger(((ASN1OctetString)obj).getOctets());
+ }
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ return getInstance(((ASN1TaggedObject)obj).getObject());
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return an Integer from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static DERInteger getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
public DERInteger(
int value)
{
{
out.writeEncoded(INTEGER, bytes);
}
+
+ public boolean equals(
+ Object o)
+ {
+ if (o == null || !(o instanceof DERInteger))
+ {
+ return false;
+ }
+
+ DERInteger other = (DERInteger)o;
+
+ if (bytes.length != other.bytes.length)
+ {
+ return false;
+ }
+
+ for (int i = 0; i != bytes.length; i++)
+ {
+ if (bytes[i] != other.bytes[i])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
}
public abstract class DERObject
implements DERTags, DEREncodable
{
- abstract void encode(DEROutputStream out)
- throws IOException;
-
public DERObject getDERObject()
{
return this;
}
+
+ abstract void encode(DEROutputStream out)
+ throws IOException;
}
{
String identifier;
+ /**
+ * return an OID from the passed in object
+ *
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static DERObjectIdentifier getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERObjectIdentifier)
+ {
+ return (DERObjectIdentifier)obj;
+ }
+
+ if (obj instanceof ASN1OctetString)
+ {
+ return new DERObjectIdentifier(((ASN1OctetString)obj).getOctets());
+ }
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ return getInstance(((ASN1TaggedObject)obj).getObject());
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return an Object Identifier from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static DERObjectIdentifier getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
+
+ DERObjectIdentifier(
+ byte[] bytes)
+ {
+ int head = bytes[0] & 0xff;
+ StringBuffer objId = new StringBuffer();
+ int value = 0;
+ boolean first = true;
+
+ for (int i = 0; i != bytes.length; i++)
+ {
+ int b = bytes[i] & 0xff;
+
+ value = value * 128 + (b & 0x7f);
+ if ((b & 0x80) == 0) // end of number reached
+ {
+ if (first)
+ {
+ switch (value / 40)
+ {
+ case 0:
+ objId.append('0');
+ break;
+ case 1:
+ objId.append('1');
+ value -= 40;
+ break;
+ default:
+ objId.append('2');
+ value -= 80;
+ }
+ first = false;
+ }
+
+ objId.append('.');
+ objId.append(Integer.toString(value));
+ value = 0;
+ }
+ }
+
+ this.identifier = objId.toString();
+ }
+
public DERObjectIdentifier(
String identifier)
{
return identifier;
}
+ private void writeField(
+ OutputStream out,
+ int fieldValue)
+ throws IOException
+ {
+ if (fieldValue >= (1 << 7))
+ {
+ if (fieldValue >= (1 << 14))
+ {
+ if (fieldValue >= (1 << 21))
+ {
+ if (fieldValue >= (1 << 28))
+ {
+ out.write((fieldValue >> 28) | 0x80);
+ }
+ out.write((fieldValue >> 21) | 0x80);
+ }
+ out.write((fieldValue >> 14) | 0x80);
+ }
+ out.write((fieldValue >> 7) | 0x80);
+ }
+ out.write(fieldValue & 0x7f);
+ }
+
void encode(
DEROutputStream out)
throws IOException
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
DEROutputStream dOut = new DEROutputStream(bOut);
- // space for 5 7 bit numbers in an int
- byte[] iBuf = new byte[5];
-
- // FIXED by Adam Megacz -- GCJ doesn't handle evaluation order properly
- String t1 = tok.nextToken();
- String t2 = tok.nextToken();
- dOut.write(Integer.parseInt(t1) * 40 + Integer.parseInt(t2));
+ writeField(bOut,
+ Integer.parseInt(tok.nextToken()) * 40
+ + Integer.parseInt(tok.nextToken()));
while (tok.hasMoreTokens())
{
- //
- // translate into base 128
- //
- int value = Integer.parseInt(tok.nextToken());
- int count = iBuf.length - 1;
-
- iBuf[count--] = (byte)(value % 128);
- value /= 128;
-
- while (value != 0)
- {
- iBuf[count--] = (byte)((value % 128) | 0x80);
- value /= 128;
- }
- dOut.write(iBuf, count + 1, iBuf.length - (count + 1));
+ writeField(bOut, Integer.parseInt(tok.nextToken()));
}
dOut.close();
import java.io.*;
public class DEROctetString
- extends DERObject
+ extends ASN1OctetString
{
- byte[] string;
-
/**
* @param string the octets making up the octet string.
*/
public DEROctetString(
byte[] string)
{
- this.string = string;
- }
-
- public DEROctetString(
- DERObject obj)
- {
- try
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- DEROutputStream dOut = new DEROutputStream(bOut);
-
- dOut.writeObject(obj);
- dOut.close();
-
- this.string = bOut.toByteArray();
- }
- catch (IOException e)
- {
- throw new IllegalArgumentException("Error processing object : " + e.toString());
- }
+ super(string);
}
public DEROctetString(
DEREncodable obj)
{
- this(obj.getDERObject());
- }
-
- public byte[] getOctets()
- {
- return string;
+ super(obj);
}
void encode(
{
out.writeEncoded(OCTET_STRING, string);
}
-
- public int hashCode()
- {
- byte[] b = this.getOctets();
- int value = 0;
-
- for (int i = 0; i != b.length; i++)
- {
- value ^= (b[i] & 0xff) << (i % 4);
- }
-
- return value;
- }
-
- public boolean equals(
- Object o)
- {
- if (o == null || !(o instanceof DEROctetString))
- {
- return false;
- }
-
- DEROctetString other = (DEROctetString)o;
-
- if (other.getOctets().length != this.getOctets().length)
- {
- return false;
- }
-
- byte[] b1 = other.getOctets();
- byte[] b2 = this.getOctets();
-
- for (int i = 0; i != b1.length; i++)
- {
- if (b1[i] != b2[i])
- {
- return false;
- }
- }
-
- return true;
- }
}
package org.bouncycastle.asn1;
-import java.io.*;
+import java.io.FilterOutputStream;
+
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.EOFException;
public class DEROutputStream
extends FilterOutputStream implements DERTags
String string;
/**
+ * return a printable string from the passed in object.
+ *
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static DERPrintableString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERPrintableString)
+ {
+ return (DERPrintableString)obj;
+ }
+
+ if (obj instanceof ASN1OctetString)
+ {
+ return new DERPrintableString(((ASN1OctetString)obj).getOctets());
+ }
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ return getInstance(((ASN1TaggedObject)obj).getObject());
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return a Printable String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static DERPrintableString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
+ /**
* basic constructor - byte encoded string.
*/
public DERPrintableString(
byte[] string)
{
- try
- {
- this.string = new String(string, "US-ASCII");
- }
- catch(UnsupportedEncodingException e)
+ char[] cs = new char[string.length];
+
+ for (int i = 0; i != cs.length; i++)
{
- throw new RuntimeException("PANIC: " + e);
+ cs[i] = (char)(string[i] & 0xff);
}
+
+ this.string = new String(cs);
}
/**
public byte[] getOctets()
{
- try
- {
- return string.getBytes("US-ASCII");
- }
- catch(UnsupportedEncodingException e)
+ char[] cs = string.toCharArray();
+ byte[] bs = new byte[cs.length];
+
+ for (int i = 0; i != cs.length; i++)
{
- throw new RuntimeException("PANIC: " + e);
+ bs[i] = (byte)cs[i];
}
+
+ return bs;
}
void encode(
{
out.writeEncoded(PRINTABLE_STRING, this.getOctets());
}
+
+ public int hashCode()
+ {
+ return this.getString().hashCode();
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof DERPrintableString))
+ {
+ return false;
+ }
+
+ DERPrintableString s = (DERPrintableString)o;
+
+ return this.getString().equals(s.getString());
+ }
}
--- /dev/null
+package org.bouncycastle.asn1;
+
+import java.io.*;
+import java.util.*;
+
+public class DERSequence
+ extends ASN1Sequence
+{
+ /**
+ * create an empty sequence
+ */
+ public DERSequence()
+ {
+ }
+
+ /**
+ * create a sequence containing one object
+ */
+ public DERSequence(
+ DEREncodable obj)
+ {
+ this.addObject(obj);
+ }
+
+ /**
+ * create a sequence containing a vector of objects.
+ */
+ public DERSequence(
+ DEREncodableVector v)
+ {
+ for (int i = 0; i != v.size(); i++)
+ {
+ this.addObject(v.get(i));
+ }
+ }
+
+ /*
+ * A note on the implementation:
+ * <p>
+ * As DER requires the constructed, definite-length model to
+ * be used for structured types, this varies slightly from the
+ * ASN.1 descriptions given. Rather than just outputing SEQUENCE,
+ * we also have to specify CONSTRUCTED, and the objects length.
+ */
+ void encode(
+ DEROutputStream out)
+ throws IOException
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ DEROutputStream dOut = new DEROutputStream(bOut);
+ Enumeration e = this.getObjects();
+
+ while (e.hasMoreElements())
+ {
+ Object obj = e.nextElement();
+
+ dOut.writeObject(obj);
+ }
+
+ dOut.close();
+
+ byte[] bytes = bOut.toByteArray();
+
+ out.writeEncoded(SEQUENCE | CONSTRUCTED, bytes);
+ }
+}
package org.bouncycastle.asn1;
import java.io.*;
+import java.util.*;
/**
- * DER Set with a single object.
+ * A DER encoded set object
*/
public class DERSet
- extends DERConstructedSet
+ extends ASN1Set
{
/**
- * @param sequence the sequence making up the set
+ * create an empty set
+ */
+ public DERSet()
+ {
+ }
+
+ /**
+ * @param obj - a single object that makes up the set.
*/
public DERSet(
- DEREncodable sequence)
+ DEREncodable obj)
{
- this.addObject(sequence);
+ this.addObject(obj);
}
- public DERObject getSequence()
+ /**
+ * @param v - a vector of objects making up the set.
+ */
+ public DERSet(
+ DEREncodableVector v)
{
- return (DERObject)this.getObjectAt(0);
+ for (int i = 0; i != v.size(); i++)
+ {
+ this.addObject(v.get(i));
+ }
+ }
+
+ /*
+ * A note on the implementation:
+ * <p>
+ * As DER requires the constructed, definite-length model to
+ * be used for structured types, this varies slightly from the
+ * ASN.1 descriptions given. Rather than just outputing SET,
+ * we also have to specify CONSTRUCTED, and the objects length.
+ */
+ void encode(
+ DEROutputStream out)
+ throws IOException
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ DEROutputStream dOut = new DEROutputStream(bOut);
+ Enumeration e = this.getObjects();
+
+ while (e.hasMoreElements())
+ {
+ Object obj = e.nextElement();
+
+ dOut.writeObject(obj);
+ }
+
+ dOut.close();
+
+ byte[] bytes = bOut.toByteArray();
+
+ out.writeEncoded(SET | CONSTRUCTED, bytes);
}
}
String string;
/**
+ * return a T61 string from the passed in object.
+ *
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static DERT61String getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERT61String)
+ {
+ return (DERT61String)obj;
+ }
+
+ if (obj instanceof ASN1OctetString)
+ {
+ return new DERT61String(((ASN1OctetString)obj).getOctets());
+ }
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ return getInstance(((ASN1TaggedObject)obj).getObject());
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return an T61 String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static DERT61String getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
+ /**
* basic constructor - with bytes.
*/
public DERT61String(
{
out.writeEncoded(T61_STRING, string.getBytes());
}
+
+ public boolean equals(
+ Object o)
+ {
+ if ((o == null) || !(o instanceof DERT61String))
+ {
+ return false;
+ }
+
+ return this.getString().equals(((DERT61String)o).getString());
+ }
}
* rules (as with sequences).
*/
public class DERTaggedObject
- extends DERObject
+ extends ASN1TaggedObject
{
- int tagNo;
- boolean empty = false;
- boolean explicit = true;
- DEREncodable obj = null;
-
- /**
- * This creates an empty tagged object of tagNo (ie. zero length).
- *
- * @param tagNo the tag number for this object.
- */
- public DERTaggedObject(
- int tagNo)
- {
- this.explicit = true;
- this.tagNo = tagNo;
- this.empty = true;
- }
-
/**
* @param tagNo the tag number for this object.
* @param obj the tagged object.
int tagNo,
DEREncodable obj)
{
- this.explicit = true;
- this.tagNo = tagNo;
- this.obj = obj;
+ super(tagNo, obj);
}
/**
- * @param explicit true if the object is explicitly tagged.
+ * @param explicit true if an explicitly tagged object.
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
int tagNo,
DEREncodable obj)
{
- this.explicit = explicit;
- this.tagNo = tagNo;
- this.obj = obj;
- }
-
- public int getTagNo()
- {
- return tagNo;
- }
-
- public boolean isExplicit()
- {
- return explicit;
- }
-
- public boolean isEmpty()
- {
- return empty;
+ super(explicit, tagNo, obj);
}
- public DERObject getObject()
+ /**
+ * create an implicitly tagged object that contains a zero
+ * length sequence.
+ */
+ public DERTaggedObject(
+ int tagNo)
{
- return obj.getDERObject();
+ super(false, tagNo, new DERSequence());
}
void encode(
if (explicit)
{
- out.writeEncoded(CONSTRUCTED | TAGGED | tagNo, bOut.toByteArray());
+ out.writeEncoded(CONSTRUCTED | TAGGED | tagNo, bytes);
}
else
{
public static final int NULL = 0x05;
public static final int OBJECT_IDENTIFIER = 0x06;
public static final int EXTERNAL = 0x08;
+ public static final int ENUMERATED = 0x0a;
public static final int SEQUENCE = 0x10;
public static final int SEQUENCE_OF = 0x10; // for completeness
public static final int SET = 0x11;
public static final int GRAPHIC_STRING = 0x19;
public static final int VISIBLE_STRING = 0x1a;
public static final int GENERAL_STRING = 0x1b;
+ public static final int UNIVERSAL_STRING = 0x1c;
public static final int BMP_STRING = 0x1e;
+ public static final int UTF8_STRING = 0x0c;
}
import java.io.*;
import java.util.*;
import java.io.*;
+import java.text.*;
/**
* UTC time object.
String time;
/**
+ * return an UTC Time from the passed in object.
+ *
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static DERUTCTime getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERUTCTime)
+ {
+ return (DERUTCTime)obj;
+ }
+
+ if (obj instanceof ASN1OctetString)
+ {
+ return new DERUTCTime(((ASN1OctetString)obj).getOctets());
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return an UTC Time from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static DERUTCTime getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
+ /**
* The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were
* never encoded. When you're creating one of these objects from scratch, that's
* what you want to use, otherwise we'll try to deal with whatever gets read from
* the input stream... (this is why the input format is different from the getTime()
* method output).
* <p>
- * You can generate a Java date string in the right format by using:
- * <pre>
- * dateF = new SimpleDateFormat("yyMMddHHmmss");
- * tz = new SimpleTimeZone(0, "Z");
- *
- * dateF.setTimeZone(tz);
- *
- * utcTime = new DERUTCTime(dateF.format(new Date()) + "Z");
- * </pre>
*
* @param time the time string.
*/
}
/**
+ * base constructer from a java.util.date object
+ */
+ public DERUTCTime(
+ Date time)
+ {
+ SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'");
+
+ dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
+
+ this.time = dateF.format(time);
+ }
+
+ DERUTCTime(
+ byte[] bytes)
+ {
+ //
+ // explicitly convert to characters
+ //
+ char[] dateC = new char[bytes.length];
+
+ for (int i = 0; i != dateC.length; i++)
+ {
+ dateC[i] = (char)(bytes[i] & 0xff);
+ }
+
+ this.time = new String(dateC);
+ }
+
+ /**
* return the time - always in the form of
* YYMMDDhhmmssGMT(+hh:mm|-hh:mm).
* <p>
* </pre>
* To read in the time and get a date which is compatible with our local
* time zone.
+ * <p>
+ * <b>Note:</b> In some cases, due to the local date processing, this
+ * may lead to unexpected results. If you want to stick the normal
+ * convention of 1950 to 2049 use the getAdjustedTime() method.
*/
public String getTime()
{
return time;
}
+ /**
+ * return the time as an adjusted date with a 4 digit year. This goes
+ * in the range of 1950 - 2049.
+ */
+ public String getAdjustedTime()
+ {
+ String d = this.getTime();
+
+ if (d.charAt(0) < '5')
+ {
+ return "20" + d;
+ }
+ else
+ {
+ return "19" + d;
+ }
+ }
+
+ private byte[] getOctets()
+ {
+ char[] cs = time.toCharArray();
+ byte[] bs = new byte[cs.length];
+
+ for (int i = 0; i != cs.length; i++)
+ {
+ bs[i] = (byte)cs[i];
+ }
+
+ return bs;
+ }
+
void encode(
DEROutputStream out)
throws IOException
{
- out.writeEncoded(UTC_TIME, time.getBytes());
+ out.writeEncoded(UTC_TIME, this.getOctets());
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if ((o == null) || !(o instanceof DERUTCTime))
+ {
+ return false;
+ }
+
+ return time.equals(((DERUTCTime)o).time);
}
}
--- /dev/null
+package org.bouncycastle.asn1;
+
+import java.io.*;
+
+/**
+ * DER UTF8String object.
+ */
+public class DERUTF8String
+ extends DERObject
+ implements DERString
+{
+ String string;
+
+ /**
+ * return an UTF8 string from the passed in object.
+ *
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static DERUTF8String getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERUTF8String)
+ {
+ return (DERUTF8String)obj;
+ }
+
+ if (obj instanceof ASN1OctetString)
+ {
+ return new DERUTF8String(((ASN1OctetString)obj).getOctets());
+ }
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ return getInstance(((ASN1TaggedObject)obj).getObject());
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return an UTF8 String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static DERUTF8String getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
+ /**
+ * basic constructor - byte encoded string.
+ */
+ DERUTF8String(
+ byte[] string)
+ {
+ int i = 0;
+ int length = 0;
+
+ while (i < string.length)
+ {
+ length++;
+ if ((string[i] & 0xe0) == 0xe0)
+ {
+ i += 3;
+ }
+ else if ((string[i] & 0xc0) == 0xc0)
+ {
+ i += 2;
+ }
+ else
+ {
+ i += 1;
+ }
+ }
+
+ char[] cs = new char[length];
+
+ i = 0;
+ length = 0;
+
+ while (i < string.length)
+ {
+ char ch;
+
+ if ((string[i] & 0xe0) == 0xe0)
+ {
+ ch = (char)(((string[i] & 0x1f) << 12)
+ | ((string[i + 1] & 0x3f) << 6) | (string[i + 2] & 0x3f));
+ i += 3;
+ }
+ else if ((string[i] & 0xc0) == 0xc0)
+ {
+ ch = (char)(((string[i] & 0x3f) << 6) | (string[i + 1] & 0x3f));
+ i += 2;
+ }
+ else
+ {
+ ch = (char)(string[i] & 0xff);
+ i += 1;
+ }
+
+ cs[length++] = ch;
+ }
+
+ this.string = new String(cs);
+ }
+
+ /**
+ * basic constructor
+ */
+ public DERUTF8String(
+ String string)
+ {
+ this.string = string;
+ }
+
+ public String getString()
+ {
+ return string;
+ }
+
+ public int hashCode()
+ {
+ return this.getString().hashCode();
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if (!(o instanceof DERUTF8String))
+ {
+ return false;
+ }
+
+ DERUTF8String s = (DERUTF8String)o;
+
+ return this.getString().equals(s.getString());
+ }
+
+ void encode(
+ DEROutputStream out)
+ throws IOException
+ {
+ char[] c = string.toCharArray();
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ for (int i = 0; i != c.length; i++)
+ {
+ char ch = c[i];
+
+ if (ch < 0x0080)
+ {
+ bOut.write(ch);
+ }
+ else if (ch < 0x0800)
+ {
+ bOut.write(0xc0 | (ch >> 6));
+ bOut.write(0x80 | (ch & 0x3f));
+ }
+ else
+ {
+ bOut.write(0xe0 | (ch >> 12));
+ bOut.write(0x80 | ((ch >> 6) & 0x3F));
+ bOut.write(0x80 | (ch & 0x3F));
+ }
+ }
+
+ out.writeEncoded(UTF8_STRING, bOut.toByteArray());
+ }
+}
--- /dev/null
+package org.bouncycastle.asn1;
+
+import java.io.*;
+
+/**
+ * DER UniversalString object.
+ */
+public class DERUniversalString
+ extends DERObject
+ implements DERString
+{
+ byte[] string;
+ char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+ /**
+ * return a Universal String from the passed in object.
+ *
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static DERUniversalString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERUniversalString)
+ {
+ return (DERUniversalString)obj;
+ }
+
+ if (obj instanceof ASN1OctetString)
+ {
+ return new DERUniversalString(((ASN1OctetString)obj).getOctets());
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return a Universal String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static DERUniversalString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
+ /**
+ * basic constructor - byte encoded string.
+ */
+ public DERUniversalString(
+ byte[] string)
+ {
+ this.string = string;
+ }
+
+ /**
+ * UniversalStrings have characters which are 4 bytes long - for the
+ * moment we just return them in Hex...
+ */
+ public String getString()
+ {
+ StringBuffer buf = new StringBuffer();
+
+ for (int i = 0; i != string.length; i++)
+ {
+ buf.append(table[(string[i] >>> 4) % 0xf]);
+ buf.append(table[string[i] & 0xf]);
+ }
+
+ return buf.toString();
+ }
+
+ public byte[] getOctets()
+ {
+ return string;
+ }
+
+ void encode(
+ DEROutputStream out)
+ throws IOException
+ {
+ out.writeEncoded(UNIVERSAL_STRING, this.getOctets());
+ }
+
+ public boolean equals(
+ Object o)
+ {
+ if ((o == null) || !(o instanceof DERUniversalString))
+ {
+ return false;
+ }
+
+ return this.getString().equals(((DERUniversalString)o).getString());
+ }
+}
{
out.writeEncoded(tag, data);
}
+
+ public boolean equals(
+ Object o)
+ {
+ if ((o == null) || !(o instanceof DERUnknownTag))
+ {
+ return false;
+ }
+
+ DERUnknownTag other = (DERUnknownTag)o;
+
+ if(tag != other.tag)
+ {
+ return false;
+ }
+
+ if(data.length != other.data.length)
+ {
+ return false;
+ }
+
+ for(int i = 0; i < data.length; i++)
+ {
+ if(data[i] != other.data[i])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
}
String string;
/**
+ * return a Visible String from the passed in object.
+ *
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static DERVisibleString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERVisibleString)
+ {
+ return (DERVisibleString)obj;
+ }
+
+ if (obj instanceof ASN1OctetString)
+ {
+ return new DERVisibleString(((ASN1OctetString)obj).getOctets());
+ }
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ return getInstance(((ASN1TaggedObject)obj).getObject());
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return a Visible String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ */
+ public static DERVisibleString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
+ /**
* basic constructor - byte encoded string.
*/
public DERVisibleString(
byte[] string)
{
- try
- {
- this.string = new String(string, "US-ASCII");
- }
- catch(UnsupportedEncodingException e)
+ char[] cs = new char[string.length];
+
+ for (int i = 0; i != cs.length; i++)
{
- throw new RuntimeException("PANIC: " + e);
+ cs[i] = (char)(string[i] & 0xff);
}
+
+ this.string = new String(cs);
}
/**
public byte[] getOctets()
{
- try
- {
- return string.getBytes("US-ASCII");
- }
- catch(UnsupportedEncodingException e)
+ char[] cs = string.toCharArray();
+ byte[] bs = new byte[cs.length];
+
+ for (int i = 0; i != cs.length; i++)
{
- throw new RuntimeException("PANIC: " + e);
+ bs[i] = (byte)cs[i];
}
+
+ return bs;
}
void encode(
{
out.writeEncoded(VISIBLE_STRING, this.getOctets());
}
+
+ public boolean equals(
+ Object o)
+ {
+ if ((o == null) || !(o instanceof DERVisibleString))
+ {
+ return false;
+ }
+
+ return this.getString().equals(((DERVisibleString)o).getString());
+ }
}
--- /dev/null
+package org.bouncycastle.asn1.cms;
+
+import org.bouncycastle.asn1.*;
+
+public class Attribute
+ implements DEREncodable
+{
+ private DERObjectIdentifier attrType;
+ private ASN1Set attrValues;
+
+ /**
+ * return an Attribute object from the given object.
+ *
+ * @param o the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ */
+ public static Attribute getInstance(
+ Object o)
+ {
+ if (o == null || o instanceof Attribute)
+ {
+ return (Attribute)o;
+ }
+
+ if (o instanceof ASN1Sequence)
+ {
+ return new Attribute((ASN1Sequence)o);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory");
+ }
+
+ public Attribute(
+ ASN1Sequence seq)
+ {
+ attrType = (DERObjectIdentifier)seq.getObjectAt(0);
+ attrValues = (ASN1Set)seq.getObjectAt(1);
+ }
+
+ public Attribute(
+ DERObjectIdentifier attrType,
+ ASN1Set attrValues)
+ {
+ this.attrType = attrType;
+ this.attrValues = attrValues;
+ }
+
+ public DERObjectIdentifier getAttrType()
+ {
+ return attrType;
+ }
+
+ public ASN1Set getAttrValues()
+ {
+ return attrValues;
+ }
+
+ /**
+ * <pre>
+ * Attribute ::= SEQUENCE {
+ * attrType OBJECT IDENTIFIER,
+ * attrValues SET OF AttributeValue
+ * }
+ * </pre>
+ */
+ public DERObject getDERObject()
+ {
+ DEREncodableVector v = new DEREncodableVector();
+
+ v.add(attrType);
+ v.add(attrValues);
+
+ return new DERSequence(v);
+ }
+}
--- /dev/null
+// Decompiled by Jad v1.5.7f. Copyright 2000 Pavel Kouznetsov.
+// Jad home page: http://www.geocities.com/SiliconValley/Bridge/8617/jad.html
+// Decompiler options: packimports(3)
+// Source File Name: SignedAttributes.java
+
+package org.bouncycastle.asn1.cms;
+
+import java.util.Vector;
+import org.bouncycastle.asn1.*;
+
+// Referenced classes of package org.bouncycastle.asn1.cms:
+// Attribute
+
+public class SignedAttributes
+ implements DEREncodable
+{
+
+ public SignedAttributes(Vector vector)
+ {
+ setAttributes(vector);
+ }
+
+ public SignedAttributes(DERConstructedSet derconstructedset)
+ {
+ attributes = derconstructedset;
+ }
+
+ public SignedAttributes(SignedAttributes signedattributes)
+ {
+ attributes = signedattributes.attributes;
+ }
+
+ public static SignedAttributes getInstance(Object obj)
+ {
+ if(obj == null)
+ return null;
+ if(obj instanceof SignedAttributes)
+ return (SignedAttributes)obj;
+ if(obj instanceof DERConstructedSet)
+ return new SignedAttributes((DERConstructedSet)obj);
+ if(obj instanceof DERTaggedObject)
+ return getInstance(((DERTaggedObject)obj).getObject());
+ else
+ throw new IllegalArgumentException("Invalid SignedAttributes");
+ }
+
+ public static SignedAttributes newInstance(Object obj)
+ {
+ if(obj == null)
+ return null;
+ if(obj instanceof SignedAttributes)
+ return new SignedAttributes((SignedAttributes)obj);
+ if(obj instanceof DERConstructedSet)
+ return new SignedAttributes((DERConstructedSet)obj);
+ if(obj instanceof DERTaggedObject)
+ return getInstance(((DERTaggedObject)obj).getObject());
+ else
+ throw new IllegalArgumentException("Invalid SignedAttributes");
+ }
+
+ public Vector getAttributes()
+ {
+ int i = attributes.getSize();
+ Vector vector = new Vector();
+ for(int j = 0; j < i; j++)
+ vector.addElement(Attribute.getInstance(attributes.getObjectAt(j)));
+
+ return vector;
+ }
+
+ private void setAttributes(Vector vector)
+ {
+ int i = vector.size();
+ attributes = new DERConstructedSet();
+ for(int j = 0; j < i; j++)
+ attributes.addObject(Attribute.getInstance(vector.elementAt(j)));
+
+ }
+
+ public DERObject getDERObject()
+ {
+ return attributes;
+ }
+
+ private DERConstructedSet attributes;
+}
static final DERObjectIdentifier md5WithRSAEncryption = new DERObjectIdentifier(pkcs_1 + ".4");
static final DERObjectIdentifier sha1WithRSAEncryption = new DERObjectIdentifier(pkcs_1 + ".5");
static final DERObjectIdentifier srsaOAEPEncryptionSET = new DERObjectIdentifier(pkcs_1 + ".6");
+ static final DERObjectIdentifier sha256WithRSAEncryption = new DERObjectIdentifier(pkcs_1 + ".11");
+ static final DERObjectIdentifier sha384WithRSAEncryption = new DERObjectIdentifier(pkcs_1 + ".12");
+ static final DERObjectIdentifier sha512WithRSAEncryption = new DERObjectIdentifier(pkcs_1 + ".13");
//
// pkcs-3 OBJECT IDENTIFIER ::= {
static final String pkcs_9 = "1.2.840.113549.1.9";
static final DERObjectIdentifier pkcs_9_at_emailAddress = new DERObjectIdentifier(pkcs_9 + ".1");
+ static final DERObjectIdentifier pkcs_9_at_unstructuredName = new DERObjectIdentifier(pkcs_9 + ".2");
+ static final DERObjectIdentifier pkcs_9_at_contentType = new DERObjectIdentifier(pkcs_9 + ".3");
+ static final DERObjectIdentifier pkcs_9_at_messageDigest = new DERObjectIdentifier(pkcs_9 + ".4");
+ static final DERObjectIdentifier pkcs_9_at_signingTime = new DERObjectIdentifier(pkcs_9 + ".5");
+ static final DERObjectIdentifier pkcs_9_at_counterSignature = new DERObjectIdentifier(pkcs_9 + ".6");
+ static final DERObjectIdentifier pkcs_9_at_challengePassword = new DERObjectIdentifier(pkcs_9 + ".7");
+ static final DERObjectIdentifier pkcs_9_at_unstructuredAddress = new DERObjectIdentifier(pkcs_9 + ".8");
+ static final DERObjectIdentifier pkcs_9_at_extendedCertificateAttributes = new DERObjectIdentifier(pkcs_9 + ".9");
+
+ static final DERObjectIdentifier pkcs_9_at_signingDescription = new DERObjectIdentifier(pkcs_9 + ".13");
+ static final DERObjectIdentifier pkcs_9_at_extensionRequest = new DERObjectIdentifier(pkcs_9 + ".14");
+ static final DERObjectIdentifier pkcs_9_at_smimeCapabilities = new DERObjectIdentifier(pkcs_9 + ".15");
+
static final DERObjectIdentifier pkcs_9_at_friendlyName = new DERObjectIdentifier(pkcs_9 + ".20");
static final DERObjectIdentifier pkcs_9_at_localKeyId = new DERObjectIdentifier(pkcs_9 + ".21");
+
static final DERObjectIdentifier x509certType = new DERObjectIdentifier(pkcs_9 + ".22.1");
//
+ // SMIME capability sub oids.
+ //
+ static final DERObjectIdentifier preferSignedData = new DERObjectIdentifier(pkcs_9 + ".15.1");
+ static final DERObjectIdentifier canNotDecryptAny = new DERObjectIdentifier(pkcs_9 + ".15.2");
+ static final DERObjectIdentifier sMIMECapabilitiesVersions = new DERObjectIdentifier(pkcs_9 + ".15.3");
+
+ //
+ // other SMIME attributes
+ //
+
+ //
+ // id-aa OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
+ // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) attributes(2)}
+ //
+ static String id_aa = "1.2.840.113549.1.9.16.2";
+
+ /*
+ * id-aa-encrypKeyPref OBJECT IDENTIFIER ::= {id-aa 11}
+ *
+ */
+ static DERObjectIdentifier id_aa_encrypKeyPref = new DERObjectIdentifier(id_aa + ".11");
+
+ //
// pkcs-12 OBJECT IDENTIFIER ::= {
// iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 }
//
implements DEREncodable
{
private DERObjectIdentifier objectId;
- private DERObject parameters;
+ private DEREncodable parameters;
private boolean parametersDefined = false;
+
+ public static AlgorithmIdentifier getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static AlgorithmIdentifier getInstance(
+ Object obj)
+ {
+ if (obj instanceof AlgorithmIdentifier)
+ {
+ return (AlgorithmIdentifier)obj;
+ }
+
+ if (obj instanceof DERObjectIdentifier)
+ {
+ return new AlgorithmIdentifier((DERObjectIdentifier)obj);
+ }
+
+ if (obj instanceof String)
+ {
+ return new AlgorithmIdentifier((String)obj);
+ }
+
+ if (obj instanceof ASN1Sequence)
+ {
+ return new AlgorithmIdentifier((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory");
+ }
public AlgorithmIdentifier(
DERObjectIdentifier objectId)
}
public AlgorithmIdentifier(
+ String objectId)
+ {
+ this.objectId = new DERObjectIdentifier(objectId);
+ }
+
+ public AlgorithmIdentifier(
DERObjectIdentifier objectId,
- DERObject parameters)
+ DEREncodable parameters)
{
parametersDefined = true;
-
this.objectId = objectId;
this.parameters = parameters;
}
public AlgorithmIdentifier(
- DERConstructedSequence obj)
+ ASN1Sequence seq)
{
- objectId = (DERObjectIdentifier)obj.getObjectAt(0);
+ objectId = (DERObjectIdentifier)seq.getObjectAt(0);
- if (obj.getSize() == 2)
+ if (seq.size() == 2)
{
parametersDefined = true;
- parameters = (DERObject)obj.getObjectAt(1);
+ parameters = seq.getObjectAt(1);
}
else
{
return objectId;
}
- public DERObject getParameters()
+ public DEREncodable getParameters()
{
return parameters;
}
*
*/
public class AuthorityKeyIdentifier
- implements DEREncodable
+ implements DEREncodable, DERTags
{
- DEROctetString keyidentifier=null;
+ ASN1OctetString keyidentifier=null;
GeneralNames certissuer=null;
DERInteger certserno=null;
+ public static AuthorityKeyIdentifier getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static AuthorityKeyIdentifier getInstance(
+ Object obj)
+ {
+ if (obj instanceof AuthorityKeyIdentifier)
+ {
+ return (AuthorityKeyIdentifier)obj;
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
+ return new AuthorityKeyIdentifier((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory");
+ }
+
public AuthorityKeyIdentifier(
- DERConstructedSequence seq)
+ ASN1Sequence seq)
{
- Enumeration e = seq.getObjects();
+ Enumeration e = seq.getObjects();
while (e.hasMoreElements())
{
switch (o.getTagNo())
{
case 0:
- this.keyidentifier= (DEROctetString)o.getObject();
+ this.keyidentifier = ASN1OctetString.getInstance(o, false);
break;
-
case 1:
- if (o.getObject() instanceof DERConstructedSequence)
- {
- this.certissuer = new GeneralNames((DERConstructedSequence)o.getObject());
- }
- else
- {
- // as it's implicitly tagged we can loose the"sequence"
- // if there is only one object.
- //
- DERConstructedSequence s = new DERConstructedSequence();
-
- s.addObject(o.getObject());
-
- this.certissuer = new GeneralNames(s);
- }
+ this.certissuer = GeneralNames.getInstance(o, false);
break;
case 2:
- //
- // implicit tagging again...
- //
- DEROctetString oct = (DEROctetString)o.getObject();
-
- this.certserno = new DERInteger(new BigInteger(oct.getOctets()));
+ this.certserno = DERInteger.getInstance(o, false);
break;
default:
throw new IllegalArgumentException("illegal tag");
Digest digest = new SHA1Digest();
byte[] resBuf = new byte[digest.getDigestSize()];
- DERBitString derpk = new DERBitString(spki.getPublicKey());
- byte[] bytes = derpk.getBytes();
+ byte[] bytes = spki.getPublicKeyData().getBytes();
digest.update(bytes, 0, bytes.length);
digest.doFinal(resBuf, 0);
- this.keyidentifier=new DEROctetString(resBuf);
+ this.keyidentifier = new DEROctetString(resBuf);
}
/**
Digest digest = new SHA1Digest();
byte[] resBuf = new byte[digest.getDigestSize()];
- DERBitString derpk = new DERBitString(spki.getPublicKey());
- byte[] bytes = derpk.getBytes();
+ byte[] bytes = spki.getPublicKeyData().getBytes();
digest.update(bytes, 0, bytes.length);
digest.doFinal(resBuf, 0);
DERBoolean cA = new DERBoolean(false);
DERInteger pathLenConstraint = null;
+ public static BasicConstraints getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static BasicConstraints getInstance(
+ Object obj)
+ {
+ if (obj instanceof BasicConstraints)
+ {
+ return (BasicConstraints)obj;
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
+ return new BasicConstraints((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory");
+ }
+
public BasicConstraints(
- DERConstructedSequence seq)
+ ASN1Sequence seq)
{
- if (seq.getSize() != 0)
+ if (seq.size() != 0)
{
this.cA = (DERBoolean)seq.getObjectAt(0);
this.pathLenConstraint = (DERInteger)seq.getObjectAt(1);
public class CRLDistPoint
implements DEREncodable
{
- DERConstructedSequence seq = null;
+ ASN1Sequence seq = null;
+ public static CRLDistPoint getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static CRLDistPoint getInstance(
+ Object obj)
+ {
+ if (obj instanceof CRLDistPoint)
+ {
+ return (CRLDistPoint)obj;
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
+ return new CRLDistPoint((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory");
+ }
+
+ public CRLDistPoint(
+ ASN1Sequence seq)
+ {
+ this.seq = seq;
+ }
+
public CRLDistPoint(
DistributionPoint[] points)
{
- seq = new DERConstructedSequence();
+ DEREncodableVector v = new DEREncodableVector();
for (int i = 0; i != points.length; i++)
{
- seq.addObject(points[i]);
+ v.add(points[i]);
}
+
+ seq = new DERSequence(v);
}
/**
--- /dev/null
+package org.bouncycastle.asn1.x509;
+
+import org.bouncycastle.asn1.*;
+
+public class CRLReason
+ extends DEREnumerated
+{
+ public static final int UNSPECIFIED = 0;
+ public static final int KEY_COMPROMISE = 1;
+ public static final int CA_COMPROMISE = 2;
+ public static final int AFFILIATION_CHANGED = 3;
+ public static final int SUPERSEDED = 4;
+ public static final int CESSATION_OF_OPERATION = 5;
+ public static final int CERTIFICATE_HOLD = 6;
+ public static final int REMOVE_FROM_CRL = 8;
+ public static final int PRIVILEGE_WITHDRAWN = 9;
+ public static final int AA_COMPROMISE = 10;
+
+ /**
+ * <pre>
+ * CRLReason ::= ENUMERATED {
+ * unspecified (0),
+ * keyCompromise (1),
+ * cACompromise (2),
+ * affiliationChanged (3),
+ * superseded (4),
+ * cessationOfOperation (5),
+ * certificateHold (6),
+ * removeFromCRL (8),
+ * privilegeWithdrawn (9),
+ * aACompromise (10)
+ * }
+ * </pre>
+ */
+ public CRLReason(
+ int reason)
+ {
+ super(reason);
+ }
+}
* signatureValue BIT STRING }
* </pre>
*/
-
public class CertificateList
- implements DEREncodable
+ implements DEREncodable
{
- DERConstructedSequence seq;
+ TBSCertList tbsCertList;
+ AlgorithmIdentifier sigAlgId;
+ DERBitString sig;
+
+ public static CertificateList getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
- TBSCertList tbsCertList;
- AlgorithmIdentifier sigAlgId;
- DERBitString sig;
+ public static CertificateList getInstance(
+ Object obj)
+ {
+ if (obj instanceof CertificateList)
+ {
+ return (CertificateList)obj;
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
+ return new CertificateList((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory");
+ }
public CertificateList(
- DERConstructedSequence seq)
+ ASN1Sequence seq)
{
- this.seq = seq;
-
- if ( seq.getObjectAt(0) instanceof TBSCertList )
- {
- tbsCertList = (TBSCertList)seq.getObjectAt(0);
- }
- else
- {
- tbsCertList = new TBSCertList((DERConstructedSequence)seq.getObjectAt(0));
- }
-
- if ( seq.getObjectAt(1) instanceof AlgorithmIdentifier )
- {
- sigAlgId = (AlgorithmIdentifier)seq.getObjectAt(1);
- }
- else
- {
- sigAlgId = new AlgorithmIdentifier((DERConstructedSequence)seq.getObjectAt(1));
- }
-
- sig = (DERBitString)seq.getObjectAt(2);
- }
-
- public TBSCertList getTBSCertList()
- {
- return tbsCertList;
- }
-
- public TBSCertList.CRLEntry[] getRevokedCertificates()
- {
- return tbsCertList.getRevokedCertificates();
- }
-
- public AlgorithmIdentifier getSignatureAlgorithm()
- {
- return sigAlgId;
- }
-
- public DERBitString getSignature()
- {
- return sig;
- }
-
- public int getVersion()
- {
- return tbsCertList.getVersion();
- }
-
- public X509Name getIssuer()
- {
- return tbsCertList.getIssuer();
- }
-
- public DERUTCTime getThisUpdate()
- {
- return tbsCertList.getThisUpdate();
- }
-
- public DERUTCTime getNextUpdate()
- {
- return tbsCertList.getNextUpdate();
- }
-
- public DERObject getDERObject()
- {
- return seq;
- }
-}
+ tbsCertList = TBSCertList.getInstance(seq.getObjectAt(0));
+ sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
+ sig = (DERBitString)seq.getObjectAt(2);
+ }
+
+ public TBSCertList getTBSCertList()
+ {
+ return tbsCertList;
+ }
+
+ public TBSCertList.CRLEntry[] getRevokedCertificates()
+ {
+ return tbsCertList.getRevokedCertificates();
+ }
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return sigAlgId;
+ }
+
+ public DERBitString getSignature()
+ {
+ return sig;
+ }
+
+ public int getVersion()
+ {
+ return tbsCertList.getVersion();
+ }
+
+ public X509Name getIssuer()
+ {
+ return tbsCertList.getIssuer();
+ }
+
+ public Time getThisUpdate()
+ {
+ return tbsCertList.getThisUpdate();
+ }
+
+ public Time getNextUpdate()
+ {
+ return tbsCertList.getNextUpdate();
+ }
+
+ public DERObject getDERObject()
+ {
+ DERConstructedSequence seq = new DERConstructedSequence();
+ seq.addObject(tbsCertList);
+ seq.addObject(sigAlgId);
+ seq.addObject(sig);
+ return seq;
+ }
+}
package org.bouncycastle.asn1.x509;
-import java.math.*;
+import java.math.BigInteger;
import java.util.*;
import org.bouncycastle.asn1.*;
{
DERInteger p, q, g;
+ public static DSAParameter getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static DSAParameter getInstance(
+ Object obj)
+ {
+ if(obj == null || obj instanceof DSAParameter)
+ {
+ return (DSAParameter)obj;
+ }
+
+ if(obj instanceof ASN1Sequence)
+ {
+ return new DSAParameter((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("Invalid DSAParameter: " + obj.getClass().getName());
+ }
+
public DSAParameter(
BigInteger p,
BigInteger q,
}
public DSAParameter(
- DERConstructedSequence seq)
+ ASN1Sequence seq)
{
Enumeration e = seq.getObjects();
public DERObject getDERObject()
{
- DERConstructedSequence seq = new DERConstructedSequence();
+ DEREncodableVector v = new DEREncodableVector();
- seq.addObject(p);
- seq.addObject(q);
- seq.addObject(g);
+ v.add(p);
+ v.add(q);
+ v.add(g);
- return seq;
+ return new DERSequence(v);
}
}
* </pre>
*/
public class DigestInfo
- implements PKCSObjectIdentifiers, DEREncodable
+ implements DEREncodable
{
private byte[] digest;
private AlgorithmIdentifier algId;
+ public static DigestInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static DigestInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof DigestInfo)
+ {
+ return (DigestInfo)obj;
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
+ return new DigestInfo((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory");
+ }
+
public DigestInfo(
AlgorithmIdentifier algId,
byte[] digest)
}
public DigestInfo(
- DERConstructedSequence seq)
+ ASN1Sequence obj)
{
- Enumeration e = seq.getObjects();
+ Enumeration e = obj.getObjects();
- algId = new AlgorithmIdentifier((DERConstructedSequence)e.nextElement());
- digest = ((DEROctetString)e.nextElement()).getOctets();
+ algId = AlgorithmIdentifier.getInstance(e.nextElement());
+ digest = ((ASN1OctetString)e.nextElement()).getOctets();
}
public AlgorithmIdentifier getAlgorithmId()
public DERObject getDERObject()
{
- DERConstructedSequence seq = new DERConstructedSequence();
+ DEREncodableVector v = new DEREncodableVector();
- seq.addObject(algId);
- seq.addObject(new DEROctetString(digest));
+ v.add(algId);
+ v.add(new DEROctetString(digest));
- return seq;
+ return new DERSequence(v);
}
}
public class DistributionPoint
implements DEREncodable
{
- DERConstructedSequence seq = null;
+ ASN1Sequence seq = null;
+
+ public static DistributionPoint getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static DistributionPoint getInstance(
+ Object obj)
+ {
+ if(obj == null || obj instanceof DistributionPoint)
+ {
+ return (DistributionPoint)obj;
+ }
+
+ if(obj instanceof ASN1Sequence)
+ {
+ return new DistributionPoint((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("Invalid DistributionPoint: " + obj.getClass().getName());
+ }
public DistributionPoint(
+ ASN1Sequence seq)
+ {
+ this.seq = seq;
+ }
+
+ public DistributionPoint(
DistributionPointName distributionPoint,
ReasonFlags reasons,
GeneralNames cRLIssuer)
{
- seq = new DERConstructedSequence();
+ DEREncodableVector v = new DEREncodableVector();
if (distributionPoint != null)
{
- seq.addObject(new DERTaggedObject(0, distributionPoint));
+ v.add(new DERTaggedObject(0, distributionPoint));
}
if (reasons != null)
{
- seq.addObject(new DERTaggedObject(1, reasons));
+ v.add(new DERTaggedObject(1, reasons));
}
if (cRLIssuer != null)
{
- seq.addObject(new DERTaggedObject(2, cRLIssuer));
+ v.add(new DERTaggedObject(2, cRLIssuer));
}
+
+ seq = new DERSequence(v);
}
/**
public class GeneralName
implements DEREncodable
{
- DEREncodable obj;
- int tag;
+ DEREncodable obj;
+ int tag;
+ boolean isInsideImplicit = false; // if we are in an implicitly tagged object
public GeneralName(
X509Name directoryName)
this.tag = tag;
}
+ /**
+ * mark whether or not we are contained inside an implicitly tagged
+ * object.
+ * @deprecated
+ */
+ public void markInsideImplicit(
+ boolean isInsideImplicit)
+ {
+ this.isInsideImplicit = isInsideImplicit;
+ }
+
public DERObject getDERObject()
{
- return new DERTaggedObject(false, tag, obj);
+ if (obj.getDERObject() instanceof ASN1Sequence)
+ {
+ return new DERTaggedObject(true, tag, obj);
+ }
+ else
+ {
+ return new DERTaggedObject(false, tag, obj);
+ }
}
}
package org.bouncycastle.asn1.x509;
+import java.util.Enumeration;
+
import org.bouncycastle.asn1.*;
public class GeneralNames
implements DEREncodable
{
- DERConstructedSequence seq;
+ ASN1Sequence seq;
+ boolean isInsideImplicit = false;
+
+ public static GeneralNames getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof GeneralNames)
+ {
+ return (GeneralNames)obj;
+ }
+
+ if (obj instanceof ASN1Sequence)
+ {
+ return new GeneralNames((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ public static GeneralNames getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
public GeneralNames(
- DERConstructedSequence seq)
+ ASN1Sequence seq)
{
this.seq = seq;
}
+ /*
+ * this is a hack! But it will have to do until the ambiguity rules
+ * get sorted out for implicit/explicit tagging...
+ * @deprecated
+ */
+ public void markInsideImplicit(
+ boolean isInsideImplicit)
+ {
+ this.isInsideImplicit = isInsideImplicit;
+ }
+
/**
* <pre>
* GeneralNames ::= SEQUENCE SIZE {1..MAX} OF GeneralName
public static final int encipherOnly = (1 << 0);
public static final int decipherOnly = (1 << 15);
- static private byte[] getUsageBytes(
- int usage)
- {
- byte[] usageBytes = new byte[2];
-
- usageBytes[0] = (byte)(usage & 0xFF);
- usageBytes[1] = (byte)((usage >> 8) & 0xFF);
-
- return usageBytes;
- }
-
/**
* Basic constructor.
*
public KeyUsage(
int usage)
{
- super(getUsageBytes(usage), 7);
+ super(getBytes(usage), getPadBits(usage));
}
public KeyUsage(
private BigInteger modulus;
private BigInteger publicExponent;
+ public static RSAPublicKeyStructure getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static RSAPublicKeyStructure getInstance(
+ Object obj)
+ {
+ if(obj == null || obj instanceof RSAPublicKeyStructure)
+ {
+ return (RSAPublicKeyStructure)obj;
+ }
+
+ if(obj instanceof ASN1Sequence)
+ {
+ return new RSAPublicKeyStructure((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("Invalid RSAPublicKeyStructure: " + obj.getClass().getName());
+ }
+
public RSAPublicKeyStructure(
BigInteger modulus,
BigInteger publicExponent)
}
public RSAPublicKeyStructure(
- DERConstructedSequence seq)
+ ASN1Sequence seq)
{
Enumeration e = seq.getObjects();
public class ReasonFlags
extends DERBitString
{
- public static final int KEY_COMPROMISE = 1;
- public static final int CA_COMPROMISE = (1 << 2);
- public static final int AFFILIATION_CHANGED = (1 << 3);
- public static final int SUPERSEDED = (1 << 4);
- public static final int CESSATION_OF_OPERATION = (1 << 5);
- public static final int CERTIFICATE_HOLD = (1 << 6);
+ public static final int UNUSED = (1 << 7);
+ public static final int KEY_COMPROMISE = (1 << 6);
+ public static final int CA_COMPROMISE = (1 << 5);
+ public static final int AFFILIATION_CHANGED = (1 << 4);
+ public static final int SUPERSEDED = (1 << 3);
+ public static final int CESSATION_OF_OPERATION = (1 << 2);
+ public static final int CERTIFICATE_HOLD = (1 << 1);
+ public static final int PRIVILEGE_WITHDRAWN = (1 << 0);
+ public static final int AA_COMPROMISE = (1 << 15);
/**
* <pre>
* certficateHold(6)
* }
* </pre>
+ * @param reasons - the bitwise OR of the Key Reason flags giving the
+ * allowed uses for the key.
*/
public ReasonFlags(
int reasons)
{
- super((byte)reasons, 1);
+ super(getBytes(reasons), getPadBits(reasons));
+ }
+
+ public ReasonFlags(
+ DERBitString reasons)
+ {
+ super(reasons.getBytes(), reasons.getPadBits());
}
}
{
private byte[] keyidentifier;
+ public static SubjectKeyIdentifier getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1OctetString.getInstance(obj, explicit));
+ }
+
+ public static SubjectKeyIdentifier getInstance(
+ Object obj)
+ {
+ if(obj == null || obj instanceof SubjectKeyIdentifier)
+ {
+ return (SubjectKeyIdentifier)obj;
+ }
+
+ if(obj instanceof SubjectPublicKeyInfo)
+ {
+ return new SubjectKeyIdentifier((SubjectPublicKeyInfo)obj);
+ }
+
+ if(obj instanceof ASN1OctetString)
+ {
+ return new SubjectKeyIdentifier((ASN1OctetString)obj);
+ }
+
+ throw new IllegalArgumentException("Invalid SubjectKeyIdentifier: " + obj.getClass().getName());
+ }
+
public SubjectKeyIdentifier(
byte[] keyid)
{
}
public SubjectKeyIdentifier(
- DEROctetString keyid)
+ ASN1OctetString keyid)
{
this.keyidentifier=keyid.getOctets();
Digest digest = new SHA1Digest();
byte[] resBuf = new byte[digest.getDigestSize()];
- DERBitString derpk = new DERBitString(spki.getPublicKey());
- byte[] bytes = derpk.getBytes();
+ byte[] bytes = spki.getPublicKeyData().getBytes();
digest.update(bytes, 0, bytes.length);
digest.doFinal(resBuf, 0);
this.keyidentifier=resBuf;
*/
public DERObject getDERObject()
{
- DEROctetString oct = new DEROctetString(keyidentifier);
- return oct;
+ return new DEROctetString(keyidentifier);
}
}
implements DEREncodable
{
private AlgorithmIdentifier algId;
- private DERObject pubKey;
+ private DERBitString keyData;
+
+ public static SubjectPublicKeyInfo getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static SubjectPublicKeyInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof SubjectPublicKeyInfo)
+ {
+ return (SubjectPublicKeyInfo)obj;
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
+ return new SubjectPublicKeyInfo((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory");
+ }
public SubjectPublicKeyInfo(
AlgorithmIdentifier algId,
- DERObject publicKey)
+ DEREncodable publicKey)
{
- this.pubKey = publicKey;
+ this.keyData = new DERBitString(publicKey);
this.algId = algId;
}
public SubjectPublicKeyInfo(
- DERConstructedSequence seq)
+ AlgorithmIdentifier algId,
+ byte[] publicKey)
{
- Enumeration e = seq.getObjects();
-
- algId = new AlgorithmIdentifier((DERConstructedSequence)e.nextElement());
-
- byte[] keyData = ((DERBitString)e.nextElement()).getBytes();
+ this.keyData = new DERBitString(publicKey);
+ this.algId = algId;
+ }
- try
- {
- ByteArrayInputStream bIn = new ByteArrayInputStream(keyData);
- DERInputStream dIn = new DERInputStream(bIn);
+ public SubjectPublicKeyInfo(
+ ASN1Sequence seq)
+ {
+ Enumeration e = seq.getObjects();
- pubKey = (DERObject)dIn.readObject();
- }
- catch (IOException ex)
- {
- throw new IllegalArgumentException("error recovering public key");
- }
+ this.algId = AlgorithmIdentifier.getInstance(e.nextElement());
+ this.keyData = (DERBitString)e.nextElement();
}
public AlgorithmIdentifier getAlgorithmId()
return algId;
}
+ /**
+ * for when the public key is an encoded object - if the bitstring
+ * can't be decoded this routine throws an IOException.
+ *
+ * @exception IOException - if the bit string doesn't represent a DER
+ * encoded object.
+ */
public DERObject getPublicKey()
+ throws IOException
+ {
+ ByteArrayInputStream bIn = new ByteArrayInputStream(keyData.getBytes());
+ DERInputStream dIn = new DERInputStream(bIn);
+
+ return dIn.readObject();
+ }
+
+ /**
+ * for when the public key is raw bits...
+ */
+ public DERBitString getPublicKeyData()
{
- return pubKey;
+ return keyData;
}
/**
DERConstructedSequence seq = new DERConstructedSequence();
seq.addObject(algId);
- seq.addObject(new DERBitString(pubKey));
+ seq.addObject(keyData);
return seq;
}
*/
public class TBSCertList
- implements DEREncodable
+ implements DEREncodable
{
- public class CRLEntry
- implements DEREncodable
- {
- DERConstructedSequence seq;
-
- DERInteger userCertificate;
- DERUTCTime revocationDate;
- X509Extensions crlEntryExtensions;
-
- public CRLEntry(
- DERConstructedSequence seq)
- {
- this.seq = seq;
-
- userCertificate = (DERInteger)seq.getObjectAt(0);
- revocationDate = (DERUTCTime)seq.getObjectAt(1);
- if ( seq.getSize() == 3 )
- {
- crlEntryExtensions = new X509Extensions((DERConstructedSequence)seq.getObjectAt(2));
- }
- }
-
- public DERInteger getUserCertificate()
- {
- return userCertificate;
- }
-
- public DERUTCTime getRevocationDate()
- {
- return revocationDate;
- }
-
- public X509Extensions getExtensions()
- {
- return crlEntryExtensions;
- }
-
- public DERObject getDERObject()
- {
- return seq;
- }
- }
-
- DERConstructedSequence seq;
+ public class CRLEntry
+ implements DEREncodable
+ {
+ DERConstructedSequence seq;
+
+ DERInteger userCertificate;
+ Time revocationDate;
+ X509Extensions crlEntryExtensions;
+
+ public CRLEntry(
+ DERConstructedSequence seq)
+ {
+ this.seq = seq;
+
+ userCertificate = (DERInteger)seq.getObjectAt(0);
+ revocationDate = Time.getInstance(seq.getObjectAt(1));
+ if (seq.getSize() == 3)
+ {
+ crlEntryExtensions = X509Extensions.getInstance(seq.getObjectAt(2));
+ }
+ }
+
+ public DERInteger getUserCertificate()
+ {
+ return userCertificate;
+ }
+
+ public Time getRevocationDate()
+ {
+ return revocationDate;
+ }
+
+ public X509Extensions getExtensions()
+ {
+ return crlEntryExtensions;
+ }
+
+ public DERObject getDERObject()
+ {
+ return seq;
+ }
+ }
+
+ ASN1Sequence seq;
DERInteger version;
AlgorithmIdentifier signature;
X509Name issuer;
- DERUTCTime thisUpdate;
- DERUTCTime nextUpdate;
- CRLEntry[] revokedCertificates;
+ Time thisUpdate;
+ Time nextUpdate;
+ CRLEntry[] revokedCertificates;
X509Extensions crlExtensions;
+ public static TBSCertList getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static TBSCertList getInstance(
+ Object obj)
+ {
+ if (obj instanceof TBSCertList)
+ {
+ return (TBSCertList)obj;
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
+ return new TBSCertList((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory");
+ }
+
public TBSCertList(
- DERConstructedSequence seq)
+ ASN1Sequence seq)
{
int seqPos = 0;
this.seq = seq;
- if ( seq.getObjectAt(seqPos) instanceof DERInteger )
+ if (seq.getObjectAt(seqPos) instanceof DERInteger)
{
version = (DERInteger)seq.getObjectAt(seqPos++);
}
version = new DERInteger(0);
}
- if ( seq.getObjectAt(seqPos) instanceof AlgorithmIdentifier )
- {
- signature = (AlgorithmIdentifier)seq.getObjectAt(seqPos++);
- }
- else
- {
- signature = new AlgorithmIdentifier((DERConstructedSequence)seq.getObjectAt(seqPos++));
- }
+ signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(seqPos++));
+ issuer = X509Name.getInstance(seq.getObjectAt(seqPos++));
+ thisUpdate = Time.getInstance(seq.getObjectAt(seqPos++));
- if ( seq.getObjectAt(seqPos) instanceof X509Name )
+ if (seqPos < seq.size()
+ && (seq.getObjectAt(seqPos) instanceof DERUTCTime
+ || seq.getObjectAt(seqPos) instanceof DERGeneralizedTime
+ || seq.getObjectAt(seqPos) instanceof Time))
{
- issuer = (X509Name)seq.getObjectAt(seqPos++);
+ nextUpdate = Time.getInstance(seq.getObjectAt(seqPos++));
}
- else
+
+ if (seqPos < seq.size()
+ && !(seq.getObjectAt(seqPos) instanceof DERTaggedObject))
{
- issuer = new X509Name((DERConstructedSequence)seq.getObjectAt(seqPos++));
- }
+ DERConstructedSequence certs = (DERConstructedSequence)seq.getObjectAt(seqPos++);
+ revokedCertificates = new CRLEntry[certs.getSize()];
- thisUpdate = (DERUTCTime)seq.getObjectAt(seqPos++);
+ for ( int i = 0; i < revokedCertificates.length; i++)
+ {
+ revokedCertificates[i] = new CRLEntry((DERConstructedSequence)certs.getObjectAt(i));
+ }
+ }
- if ( seqPos < seq.getSize()
- && seq.getObjectAt(seqPos) instanceof DERUTCTime )
+ if (seqPos < seq.size()
+ && seq.getObjectAt(seqPos) instanceof DERTaggedObject)
{
- nextUpdate = (DERUTCTime)seq.getObjectAt(seqPos++);
+ crlExtensions = X509Extensions.getInstance(seq.getObjectAt(seqPos++));
}
-
- if ( seqPos < seq.getSize()
- && !(seq.getObjectAt(seqPos) instanceof DERTaggedObject) )
- {
- DERConstructedSequence certs = (DERConstructedSequence)seq.getObjectAt(seqPos++);
- revokedCertificates = new CRLEntry[certs.getSize()];
-
- for ( int i = 0; i < revokedCertificates.length; i++ )
- {
- revokedCertificates[i] = new CRLEntry((DERConstructedSequence)certs.getObjectAt(i));
- }
- }
-
- if ( seqPos < seq.getSize()
- && seq.getObjectAt(seqPos) instanceof DERTaggedObject )
- {
- crlExtensions = new X509Extensions((DERConstructedSequence)((DERTaggedObject)seq.getObjectAt(seqPos++)).getObject());
- }
}
public int getVersion()
return issuer;
}
- public DERUTCTime getThisUpdate()
+ public Time getThisUpdate()
{
return thisUpdate;
}
- public DERUTCTime getNextUpdate()
+ public Time getNextUpdate()
{
return nextUpdate;
}
return seq;
}
}
-
public class TBSCertificateStructure
implements DEREncodable, X509ObjectIdentifiers, PKCSObjectIdentifiers
{
- DERConstructedSequence seq;
+ ASN1Sequence seq;
DERInteger version;
DERInteger serialNumber;
AlgorithmIdentifier signature;
X509Name issuer;
- DERUTCTime startDate, endDate;
+ Time startDate, endDate;
X509Name subject;
SubjectPublicKeyInfo subjectPublicKeyInfo;
DERBitString issuerUniqueId;
DERBitString subjectUniqueId;
X509Extensions extensions;
+ public static TBSCertificateStructure getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static TBSCertificateStructure getInstance(
+ Object obj)
+ {
+ if (obj instanceof TBSCertificateStructure)
+ {
+ return (TBSCertificateStructure)obj;
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
+ return new TBSCertificateStructure((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory");
+ }
+
public TBSCertificateStructure(
- DERConstructedSequence seq)
+ ASN1Sequence seq)
{
int seqStart = 0;
//
if (seq.getObjectAt(0) instanceof DERTaggedObject)
{
- version = (DERInteger)((DERTaggedObject)seq.getObjectAt(0)).getObject();
+ version = DERInteger.getInstance(seq.getObjectAt(0));
}
else
{
version = new DERInteger(0);
}
- serialNumber = (DERInteger)seq.getObjectAt(seqStart + 1);
+ serialNumber = DERInteger.getInstance(seq.getObjectAt(seqStart + 1));
- if (seq.getObjectAt(seqStart + 2) instanceof AlgorithmIdentifier)
- {
- signature = (AlgorithmIdentifier)seq.getObjectAt(seqStart + 2);
- }
- else
- {
- signature = new AlgorithmIdentifier((DERConstructedSequence)seq.getObjectAt(seqStart + 2));
- }
-
- if (seq.getObjectAt(seqStart + 3) instanceof X509Name)
- {
- issuer = (X509Name)seq.getObjectAt(seqStart + 3);
- }
- else
- {
- issuer = new X509Name((DERConstructedSequence)seq.getObjectAt(seqStart + 3));
- }
+ signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(seqStart + 2));
+ issuer = X509Name.getInstance(seq.getObjectAt(seqStart + 3));
//
// before and after dates
//
- DERConstructedSequence dates = (DERConstructedSequence)seq.getObjectAt(seqStart + 4);
- startDate = (DERUTCTime)dates.getObjectAt(0);
- endDate = (DERUTCTime)dates.getObjectAt(1);
+ ASN1Sequence dates = (ASN1Sequence)seq.getObjectAt(seqStart + 4);
- if (seq.getObjectAt(seqStart + 5) instanceof X509Name)
- {
- subject = (X509Name)seq.getObjectAt(seqStart + 5);
- }
- else
- {
- subject = new X509Name((DERConstructedSequence)seq.getObjectAt(seqStart + 5));
- }
+ startDate = Time.getInstance(dates.getObjectAt(0));
+ endDate = Time.getInstance(dates.getObjectAt(1));
+
+ subject = X509Name.getInstance(seq.getObjectAt(seqStart + 5));
//
// public key info.
//
- if (seq.getObjectAt(seqStart + 6) instanceof SubjectPublicKeyInfo)
- {
- subjectPublicKeyInfo = (SubjectPublicKeyInfo)seq.getObjectAt(seqStart + 6);
- }
- else
- {
- subjectPublicKeyInfo = new SubjectPublicKeyInfo((DERConstructedSequence)seq.getObjectAt(seqStart + 6));
- }
+ subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(seq.getObjectAt(seqStart + 6));
- for (int extras = seq.getSize() - (seqStart + 6) - 1; extras > 0; extras--)
+ for (int extras = seq.size() - (seqStart + 6) - 1; extras > 0; extras--)
{
DERTaggedObject extra = (DERTaggedObject)seq.getObjectAt(seqStart + 6 + extras);
switch (extra.getTagNo())
{
case 1:
- issuerUniqueId = (DERBitString)extra.getObject();
+ issuerUniqueId = DERBitString.getInstance(extra);
break;
case 2:
- subjectUniqueId = (DERBitString)extra.getObject();
+ subjectUniqueId = DERBitString.getInstance(extra);
break;
case 3:
- extensions = new X509Extensions((DERConstructedSequence)extra.getObject());
+ extensions = X509Extensions.getInstance(extra);
}
}
}
return issuer;
}
- public DERUTCTime getStartDate()
+ public Time getStartDate()
{
return startDate;
}
- public DERUTCTime getEndDate()
+ public Time getEndDate()
{
return endDate;
}
--- /dev/null
+package org.bouncycastle.asn1.x509;
+
+import java.util.Date;
+import java.util.SimpleTimeZone;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+
+import org.bouncycastle.asn1.*;
+
+public class Time
+ implements DEREncodable
+{
+ DERObject time;
+
+ public static Time getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(obj.getObject());
+ }
+
+ public Time(
+ DERObject time)
+ {
+ if (!(time instanceof DERUTCTime)
+ && !(time instanceof DERGeneralizedTime))
+ {
+ throw new IllegalArgumentException("unknown object passed to Time");
+ }
+
+ this.time = time;
+ }
+
+ /**
+ * creates a time object from a given date - if the date is between 1950
+ * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime
+ * is used.
+ */
+ public Time(
+ Date date)
+ {
+ SimpleTimeZone tz = new SimpleTimeZone(0, "Z");
+ SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss");
+
+ dateF.setTimeZone(tz);
+
+ String d = dateF.format(date) + "Z";
+ int year = Integer.parseInt(d.substring(0, 4));
+
+ if (year < 1950 || year > 2049)
+ {
+ time = new DERGeneralizedTime(d);
+ }
+ else
+ {
+ time = new DERUTCTime(d.substring(2));
+ }
+ }
+
+ public static Time getInstance(
+ Object obj)
+ {
+ if (obj instanceof Time)
+ {
+ return (Time)obj;
+ }
+ else if (obj instanceof DERUTCTime)
+ {
+ return new Time((DERUTCTime)obj);
+ }
+ else if (obj instanceof DERGeneralizedTime)
+ {
+ return new Time((DERGeneralizedTime)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory");
+ }
+
+ public String getTime()
+ {
+ if (time instanceof DERUTCTime)
+ {
+ return ((DERUTCTime)time).getAdjustedTime();
+ }
+ else
+ {
+ return ((DERGeneralizedTime)time).getTime();
+ }
+ }
+
+ public Date getDate()
+ {
+ SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
+
+ return dateF.parse(this.getTime(), new ParsePosition(0));
+ }
+
+ /**
+ * <pre>
+ * Time ::= CHOICE {
+ * utcTime UTCTime,
+ * generalTime GeneralizedTime }
+ * </pre>
+ */
+ public DERObject getDERObject()
+ {
+ return time;
+ }
+}
DERInteger serialNumber;
AlgorithmIdentifier signature;
X509Name issuer;
- DERUTCTime startDate, endDate;
+ Time startDate, endDate;
X509Name subject;
SubjectPublicKeyInfo subjectPublicKeyInfo;
}
public void setStartDate(
- DERUTCTime startDate)
+ Time startDate)
{
this.startDate = startDate;
}
+ public void setStartDate(
+ DERUTCTime startDate)
+ {
+ this.startDate = new Time(startDate);
+ }
+
public void setEndDate(
- DERUTCTime endDate)
+ Time endDate)
{
this.endDate = endDate;
}
+ public void setEndDate(
+ DERUTCTime endDate)
+ {
+ this.endDate = new Time(endDate);
+ }
+
public void setSubject(
X509Name subject)
{
package org.bouncycastle.asn1.x509;
+import java.io.*;
import java.util.Vector;
import java.util.Enumeration;
AlgorithmIdentifier signature;
X509Name issuer;
- DERUTCTime thisUpdate, nextUpdate=null;
+ Time thisUpdate, nextUpdate=null;
X509Extensions extensions=null;
private Vector crlentries=null;
public void setThisUpdate(
DERUTCTime thisUpdate)
{
- this.thisUpdate = thisUpdate;
+ this.thisUpdate = new Time(thisUpdate);
}
public void setNextUpdate(
DERUTCTime nextUpdate)
{
- this.nextUpdate = nextUpdate;
+ this.nextUpdate = new Time(nextUpdate);
+ }
+
+ public void setThisUpdate(
+ Time thisUpdate)
+ {
+ this.thisUpdate = thisUpdate;
}
+ public void setNextUpdate(
+ Time nextUpdate)
+ {
+ this.nextUpdate = nextUpdate;
+ }
public void addCRLEntry(
DERConstructedSequence crlEntry)
public void addCRLEntry(DERInteger userCertificate, DERUTCTime revocationDate, int reason)
{
+ addCRLEntry(userCertificate, new Time(revocationDate), reason);
+ }
+
+ public void addCRLEntry(DERInteger userCertificate, Time revocationDate, int reason)
+ {
DERConstructedSequence seq = new DERConstructedSequence();
seq.addObject(userCertificate);
seq.addObject(revocationDate);
+
if (reason != 0)
{
- ReasonFlags rf = new ReasonFlags(reason);
+ CRLReason rf = new CRLReason(reason);
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ DEROutputStream dOut = new DEROutputStream(bOut);
+ try
+ {
+ dOut.writeObject(rf);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("error encoding value: " + e);
+ }
+ byte[] value = bOut.toByteArray();
DERConstructedSequence eseq = new DERConstructedSequence();
- eseq.addObject(X509Extensions.ReasonCode);
- eseq.addObject(rf);
+ DERConstructedSequence eseq1 = new DERConstructedSequence();
+ eseq1.addObject(X509Extensions.ReasonCode);
+ eseq1.addObject(new DEROctetString(value));
+ eseq.addObject(eseq1);
X509Extensions ex = new X509Extensions(eseq);
seq.addObject(ex);
}
if (extensions != null)
{
- seq.addObject(new DERTaggedObject(0, extensions.getDERObject()));
+ seq.addObject(new DERTaggedObject(0, extensions));
}
return new TBSCertList(seq);
DERInteger serialNumber;
AlgorithmIdentifier signature;
X509Name issuer;
- DERUTCTime startDate, endDate;
+ Time startDate, endDate;
X509Name subject;
SubjectPublicKeyInfo subjectPublicKeyInfo;
X509Extensions extensions;
public void setStartDate(
DERUTCTime startDate)
{
+ this.startDate = new Time(startDate);
+ }
+
+ public void setStartDate(
+ Time startDate)
+ {
this.startDate = startDate;
}
public void setEndDate(
DERUTCTime endDate)
{
+ this.endDate = new Time(endDate);
+ }
+
+ public void setEndDate(
+ Time endDate)
+ {
this.endDate = endDate;
}
if (extensions != null)
{
- seq.addObject(new DERTaggedObject(3, extensions.getDERObject()));
+ seq.addObject(new DERTaggedObject(3, extensions));
}
return new TBSCertificateStructure(seq);
public class X509CertificateStructure
implements DEREncodable, X509ObjectIdentifiers, PKCSObjectIdentifiers
{
- DERConstructedSequence seq;
+ ASN1Sequence seq;
TBSCertificateStructure tbsCert;
AlgorithmIdentifier sigAlgId;
DERBitString sig;
+ public static X509CertificateStructure getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static X509CertificateStructure getInstance(
+ Object obj)
+ {
+ if (obj instanceof X509CertificateStructure)
+ {
+ return (X509CertificateStructure)obj;
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
+ return new X509CertificateStructure((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory");
+ }
+
public X509CertificateStructure(
- DERConstructedSequence seq)
+ ASN1Sequence seq)
{
this.seq = seq;
//
// correct x509 certficate
//
- if (seq.getSize() == 3)
+ if (seq.size() == 3)
{
- if (seq.getObjectAt(0) instanceof TBSCertificateStructure)
- {
- tbsCert = (TBSCertificateStructure)seq.getObjectAt(0);
- }
- else
- {
- tbsCert = new TBSCertificateStructure((DERConstructedSequence)seq.getObjectAt(0));
- }
-
- if (seq.getObjectAt(1) instanceof AlgorithmIdentifier)
- {
- sigAlgId = (AlgorithmIdentifier)seq.getObjectAt(1);
- }
- else
- {
- sigAlgId = new AlgorithmIdentifier((DERConstructedSequence)seq.getObjectAt(1));
- }
+ tbsCert = TBSCertificateStructure.getInstance(seq.getObjectAt(0));
+ sigAlgId = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
sig = (DERBitString)seq.getObjectAt(2);
}
return tbsCert.getIssuer();
}
- public DERUTCTime getStartDate()
+ public Time getStartDate()
{
return tbsCert.getStartDate();
}
- public DERUTCTime getEndDate()
+ public Time getEndDate()
{
return tbsCert.getEndDate();
}
*/
public static final DERObjectIdentifier PolicyConstraints = new DERObjectIdentifier("2.5.29.36");
+ /**
+ * Extended Key Usage
+ */
+ public static final DERObjectIdentifier ExtendedKeyUsage = new DERObjectIdentifier("2.5.29.37");
+
private Hashtable extensions = new Hashtable();
private Vector ordering = new Vector();
- private DERConstructedSequence seq;
+
+ public static X509Extensions getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static X509Extensions getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof X509Extensions)
+ {
+ return (X509Extensions)obj;
+ }
+
+ if (obj instanceof ASN1Sequence)
+ {
+ return new X509Extensions((ASN1Sequence)obj);
+ }
+
+ if (obj instanceof ASN1TaggedObject)
+ {
+ return getInstance(((ASN1TaggedObject)obj).getObject());
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
/**
* Constructor from DERConstructedSequence.
* the extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString)
*/
public X509Extensions(
- DERConstructedSequence seq)
+ ASN1Sequence seq)
{
- this.seq = seq;
-
Enumeration e = seq.getObjects();
while (e.hasMoreElements())
{
- DERConstructedSequence s = (DERConstructedSequence)e.nextElement();
+ ASN1Sequence s = (ASN1Sequence)e.nextElement();
Enumeration e1 = s.getObjects();
- if (s.getSize() == 3)
+ if (s.size() == 3)
{
extensions.put(s.getObjectAt(0), new X509Extension((DERBoolean)s.getObjectAt(1), (DEROctetString)s.getObjectAt(2)));
}
Vector ordering,
Hashtable extensions)
{
- this.seq = new DERConstructedSequence();
+ Enumeration e;
if (ordering == null)
{
- Enumeration e = extensions.keys();
-
- ordering = this.ordering;
+ e = extensions.keys();
+ }
+ else
+ {
+ e = ordering.elements();
+ }
- while (e.hasMoreElements())
- {
- this.ordering.addElement(e.nextElement());
- }
+ while (e.hasMoreElements())
+ {
+ this.ordering.addElement(e.nextElement());
}
- Enumeration e = ordering.elements();
+ e = this.ordering.elements();
while (e.hasMoreElements())
{
DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement();
X509Extension ext = (X509Extension)extensions.get(oid);
- DERConstructedSequence s = new DERConstructedSequence();
-
- s.addObject(oid);
-
- if (ext.isCritical())
- {
- s.addObject(new DERBoolean(true));
- }
-
- s.addObject(ext.getValue());
- seq.addObject(s);
+ this.extensions.put(oid, ext);
}
}
public DERObject getDERObject()
{
- return seq;
+ DEREncodableVector vec = new DEREncodableVector();
+ Enumeration e = ordering.elements();
+
+ while (e.hasMoreElements())
+ {
+ DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement();
+ X509Extension ext = (X509Extension)extensions.get(oid);
+ DEREncodableVector v = new DEREncodableVector();
+
+ v.add(oid);
+
+ if (ext.isCritical())
+ {
+ v.add(new DERBoolean(true));
+ }
+
+ v.add(ext.getValue());
+
+ vec.add(new DERSequence(v));
+ }
+
+ return new DERSequence(vec);
}
public int hashCode()
public static final DERObjectIdentifier OU = new DERObjectIdentifier("2.5.4.11");
/**
+ * Title
+ */
+ public static final DERObjectIdentifier T = new DERObjectIdentifier("2.5.4.12");
+
+ /**
* common name - StringType(SIZE(1..64))
*/
public static final DERObjectIdentifier CN = new DERObjectIdentifier("2.5.4.3");
*/
public static final DERObjectIdentifier ST = new DERObjectIdentifier("2.5.4.8");
+
/**
* email address (RSA PKCS#9 extension) - IA5String
* <p>
* note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here.
*/
public static final DERObjectIdentifier EmailAddress = new DERObjectIdentifier("1.2.840.113549.1.9.1");
+
+ /**
+ * email address in Verisign certificates
+ */
+ public static final DERObjectIdentifier E = EmailAddress;
+
+ /*
+ * others...
+ */
+ public static final DERObjectIdentifier DC = new DERObjectIdentifier("0.9.2342.19200300.100.1.25");
+
+ /**
+ * LDAP User id.
+ */
+ public static final DERObjectIdentifier UID = new DERObjectIdentifier("0.9.2342.19200300.100.1.1");
/**
* look up table translating OID values into their common symbols.
{
OIDLookUp.put(C, "C");
OIDLookUp.put(O, "O");
+ OIDLookUp.put(T, "T");
OIDLookUp.put(OU, "OU");
OIDLookUp.put(CN, "CN");
OIDLookUp.put(L, "L");
OIDLookUp.put(ST, "ST");
OIDLookUp.put(SN, "SN");
- OIDLookUp.put(EmailAddress, "EmailAddress");
-
- SymbolLookUp.put("C", C);
- SymbolLookUp.put("O", O);
- SymbolLookUp.put("OU", OU);
- SymbolLookUp.put("CN", CN);
- SymbolLookUp.put("L", L);
- SymbolLookUp.put("ST", ST);
- SymbolLookUp.put("SN", SN);
- SymbolLookUp.put("EmailAddress", EmailAddress);
+ OIDLookUp.put(EmailAddress, "E");
+ OIDLookUp.put(DC, "DC");
+ OIDLookUp.put(UID, "UID");
+
+ SymbolLookUp.put("c", C);
+ SymbolLookUp.put("o", O);
+ SymbolLookUp.put("t", T);
+ SymbolLookUp.put("ou", OU);
+ SymbolLookUp.put("cn", CN);
+ SymbolLookUp.put("l", L);
+ SymbolLookUp.put("st", ST);
+ SymbolLookUp.put("sn", SN);
+ SymbolLookUp.put("emailaddress", E);
+ SymbolLookUp.put("dc", DC);
+ SymbolLookUp.put("e", E);
+ SymbolLookUp.put("uid", UID);
}
private Vector ordering = new Vector();
- private Hashtable attributes = new Hashtable();
- private DERConstructedSequence seq = null;
+ private Vector values = new Vector();
+ private ASN1Sequence seq;
+
+ public static X509Name getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static X509Name getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof X509Name)
+ {
+ return (X509Name)obj;
+ }
+ else if (obj instanceof ASN1Sequence)
+ {
+ return new X509Name((ASN1Sequence)obj);
+ }
+
+ throw new IllegalArgumentException("unknown object in factory");
+ }
/**
- * Constructor from DERConstructedSequence.
+ * Constructor from ASN1Sequence
*
* the principal will be a list of constructed sets, each containing an (OID, String) pair.
*/
public X509Name(
- DERConstructedSequence seq)
+ ASN1Sequence seq)
{
- this.seq = seq;
+ this.seq = seq;
Enumeration e = seq.getObjects();
while (e.hasMoreElements())
{
- DERSet set = (DERSet)e.nextElement();
- DERConstructedSequence s = (DERConstructedSequence)set.getSequence();
+ ASN1Set set = (ASN1Set)e.nextElement();
+ ASN1Sequence s = (ASN1Sequence)set.getObjectAt(0);
ordering.addElement(s.getObjectAt(0));
- attributes.put(s.getObjectAt(0), ((DERString)s.getObjectAt(1)).getString());
+ values.addElement(((DERString)s.getObjectAt(1)).getString());
}
}
throw new IllegalArgumentException("No attribute for object id - " + oid.getId() + " - passed to distinguished name");
}
- this.attributes.put(oid, attributes.get(oid)); // copy the hash table
+ this.values.addElement(attributes.get(oid)); // copy the hash table
+ }
+ }
+
+ /**
+ * takes two vectors one of the oids and the other of the values.
+ */
+ public X509Name(
+ Vector ordering,
+ Vector values)
+ {
+ if (ordering.size() != values.size())
+ {
+ throw new IllegalArgumentException("ordering vector must be same length as values.");
+ }
+
+ for (int i = 0; i < ordering.size(); i++)
+ {
+ this.ordering.addElement(ordering.elementAt(i));
+ this.values.addElement(values.elementAt(i));
}
}
throw new IllegalArgumentException("badly formated directory string");
}
- String name = token.substring(0, index);
- String value = token.substring(index + 1);
+ String name = token.substring(0, index);
+ String value = token.substring(index + 1);
+ DERObjectIdentifier oid = null;
- DERObjectIdentifier oid = (DERObjectIdentifier)SymbolLookUp.get(name);
- if (oid == null)
+ if (name.toUpperCase().startsWith("OID."))
{
- throw new IllegalArgumentException("Unknown object id - " + oid.getId() + " - passed to distinguished name");
+ oid = new DERObjectIdentifier(name.substring(4));
+ }
+ else if (name.charAt(0) >= '0' && name.charAt(0) <= '9')
+ {
+ oid = new DERObjectIdentifier(name);
+ }
+ else
+ {
+ oid = (DERObjectIdentifier)SymbolLookUp.get(name.toLowerCase());
+ if (oid == null)
+ {
+ throw new IllegalArgumentException("Unknown object id - " + name + " - passed to distinguished name");
+ }
}
this.ordering.addElement(oid);
- this.attributes.put(oid, value);
+ this.values.addElement(value);
}
}
+ /**
+ * return false if we have characters out of the range of a printable
+ * string, true otherwise.
+ */
+ private boolean canBePrintable(
+ String str)
+ {
+ for (int i = str.length() - 1; i >= 0; i--)
+ {
+ if (str.charAt(i) > 0x007f)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
public DERObject getDERObject()
{
if (seq == null)
{
- seq = new DERConstructedSequence();
+ DEREncodableVector vec = new DEREncodableVector();
for (int i = 0; i != ordering.size(); i++)
{
- DERConstructedSequence s = new DERConstructedSequence();
+ DEREncodableVector v = new DEREncodableVector();
DERObjectIdentifier oid = (DERObjectIdentifier)ordering.elementAt(i);
- s.addObject(oid);
+ v.add(oid);
+
+ String str = (String)values.elementAt(i);
+
if (oid.equals(EmailAddress))
{
- s.addObject(new DERIA5String((String)attributes.get(oid)));
+ v.add(new DERIA5String(str));
}
else
{
- s.addObject(new DERPrintableString((String)attributes.get(oid)));
+ if (canBePrintable(str))
+ {
+ v.add(new DERPrintableString(str));
+ }
+ else
+ {
+ v.add(new DERUTF8String(str));
+ }
}
- seq.addObject(new DERSet(s));
+ vec.add(new DERSet(new DERSequence(v)));
}
- }
- return seq;
- }
-
- public int hashCode()
- {
- Enumeration e = attributes.keys();
- int hashCode = 0;
-
- while (e.hasMoreElements())
- {
- Object o = e.nextElement();
-
- hashCode ^= o.hashCode();
- hashCode ^= attributes.get(o).hashCode();
+ seq = new DERSequence(vec);
}
- for (int i = 0; i != ordering.size(); i++)
- {
- hashCode ^= ordering.elementAt(i).hashCode();
- }
-
- return hashCode;
+ return seq;
}
- public boolean equals(
- Object o)
+ /**
+ * test for equality - note: case is ignored.
+ */
+ public boolean equals(Object _obj)
{
- if (o == null || !(o instanceof X509Name))
+ if (_obj == this)
{
- return false;
+ return true;
}
- X509Name other = (X509Name)o;
-
- if (ordering.size() != other.ordering.size())
+ if (_obj == null || !(_obj instanceof X509Name))
{
return false;
}
+
+ X509Name _oxn = (X509Name)_obj;
+ int _orderingSize = ordering.size();
- for (int i = 0; i != ordering.size(); i++)
+ if (_orderingSize != _oxn.ordering.size())
{
- if (!ordering.elementAt(i).equals(other.ordering.elementAt(i)))
- {
- return false;
- }
- }
-
- Enumeration e1 = attributes.keys();
- Enumeration e2 = other.attributes.keys();
-
- while (e1.hasMoreElements() && e2.hasMoreElements())
- {
- Object o1 = e1.nextElement();
- Object o2 = e2.nextElement();
-
- if (!o1.equals(o2))
- {
- return false;
- }
- }
+ return false;
+ }
+
+ boolean[] _indexes = new boolean[_orderingSize];
+
+ for(int i = 0; i < _orderingSize; i++)
+ {
+ boolean _found = false;
+ String _oid = ((DERObjectIdentifier)ordering.elementAt(i)).getId();
+ String _val = (String)values.elementAt(i);
+
+ for(int j = 0; j < _orderingSize; j++)
+ {
+ if(_indexes[j] == true)
+ {
+ continue;
+ }
+
+ String _oOID = ((DERObjectIdentifier)_oxn.ordering.elementAt(j)).getId();
+ String _oVal = (String)_oxn.values.elementAt(j);
+
+ // was equalsIgnoreCase but MIDP doesn't like that.
+ if(_oid.equals(_oOID) && _val.toLowerCase().equals(_oVal.toLowerCase()))
+ {
+ _indexes[j] = true;
+ _found = true;
+ break;
+ }
+
+ }
+
+ if(!_found)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public int hashCode()
+ {
+ ASN1Sequence seq = (ASN1Sequence)this.getDERObject();
+ Enumeration e = seq.getObjects();
+ int hashCode = 0;
- if (e1.hasMoreElements() || e2.hasMoreElements())
+ while (e.hasMoreElements())
{
- return false;
+ hashCode ^= e.nextElement().hashCode();
}
- return true;
+ return hashCode;
}
public String toString()
{
- StringBuffer buf = new StringBuffer();
- boolean first = true;
+ StringBuffer buf = new StringBuffer();
+ boolean first = true;
+ Enumeration e1 = ordering.elements();
+ Enumeration e2 = values.elements();
- for (int i = 0; i != ordering.size(); i++)
+ while (e1.hasMoreElements())
{
- Object oid = ordering.elementAt(i);
- String sym = (String)OIDLookUp.get(oid);
+ Object oid = e1.nextElement();
+ String sym = (String)OIDLookUp.get(oid);
if (first)
{
}
else
{
- buf.append(", ");
+ buf.append(",");
}
if (sym != null)
{
buf.append(sym);
- buf.append("=");
- buf.append((String)attributes.get(oid));
}
else
{
buf.append(((DERObjectIdentifier)oid).getId());
- buf.append("=");
- buf.append((String)attributes.get(oid));
+ }
+
+ buf.append("=");
+
+ int index = buf.length();
+
+ buf.append((String)e2.nextElement());
+
+ int end = buf.length();
+
+ while (index != end)
+ {
+ if ((buf.charAt(index) == ',')
+ || (buf.charAt(index) == '"')
+ || (buf.charAt(index) == '\\')
+ || (buf.charAt(index) == '+')
+ || (buf.charAt(index) == '<')
+ || (buf.charAt(index) == '>')
+ || (buf.charAt(index) == ';'))
+ {
+ buf.insert(index, "\\");
+ index++;
+ end++;
+ }
+
+ index++;
}
}
package org.bouncycastle.asn1.x509;
/**
- * class for breaking up an X509 Name into it's component tokens, ala
+ * class for breaking up an X500 Name into it's component tokens, ala
* java.util.StringTokenizer. We need this class as some of the
* lightweight Java environment don't support classes like
* StringTokenizer.
*/
public class X509NameTokenizer
{
- private String oid;
- private int index;
+ private String oid;
+ private int index;
+ private StringBuffer buf = new StringBuffer();
public X509NameTokenizer(
String oid)
{
this.oid = oid;
- this.index = 0;
+ this.index = -1;
}
public boolean hasMoreTokens()
{
- return (index != -1);
+ return (index != oid.length());
}
public String nextToken()
{
- if (index == -1)
+ if (index == oid.length())
{
return null;
}
- String token;
- int end = oid.indexOf(',', index);
+ int end = index + 1;
+ boolean quoted = false;
+ boolean escaped = false;
- if (end == -1)
+ buf.setLength(0);
+
+ while (end != oid.length())
{
- token = oid.substring(index);
- index = -1;
- return token.trim();
- }
+ char c = oid.charAt(end);
- token = oid.substring(index, end);
+ if (c == '"')
+ {
+ if (!escaped)
+ {
+ quoted = !quoted;
+ }
+ else
+ {
+ buf.append(c);
+ }
+ escaped = false;
+ }
+ else
+ {
+ if (escaped || quoted)
+ {
+ buf.append(c);
+ escaped = false;
+ }
+ else if (c == '\\')
+ {
+ escaped = true;
+ }
+ else if (c == ',')
+ {
+ break;
+ }
+ else
+ {
+ buf.append(c);
+ }
+ }
+ end++;
+ }
- index = end + 1;
- return token.trim();
+ index = end;
+ return buf.toString().trim();
}
}
/**
* implementation of MD2
* as outlined in RFC1319 by B.Kaliski from RSA Laboratories April 1992
- *
- * @author Michael Lee
*/
public class MD2Digest\r
implements Digest\r
package org.bouncycastle.crypto.encodings;
import java.math.BigInteger;
-import java.util.Random;
import java.security.SecureRandom;
import org.bouncycastle.crypto.CipherParameters;
{
private static int HEADER_LENGTH = 10;
- // HACK
- //private SecureRandom random;
- private Random random = new Random();
-
+ private SecureRandom random;
private AsymmetricBlockCipher engine;
private boolean forEncryption;
private boolean forPrivateKey;
CipherParameters param)
{
AsymmetricKeyParameter kParam;
+
if (param instanceof ParametersWithRandom)
{
ParametersWithRandom rParam = (ParametersWithRandom)param;
- // HACK
- //this.random = rParam.getRandom();
+ this.random = rParam.getRandom();
kParam = (AsymmetricKeyParameter)rParam.getParameters();
}
else
{
- // HACK
- //this.random = new SecureRandom();
+ this.random = new SecureRandom();
kParam = (AsymmetricKeyParameter)param;
}
throws InvalidCipherTextException
{
byte[] block = engine.processBlock(in, inOff, inLen);
+
if (block.length < getOutputBlockSize())
{
throw new InvalidCipherTextException("block truncated");
/**
* initialise the RSA engine.
*
- * @param forEncryption treu if we are encrypting, false otherwise.
+ * @param forEncryption true if we are encrypting, false otherwise.
* @param param the necessary RSA key parameters.
*/
public void init(
if (forEncryption)
{
- if ((bitSize % 8) == 0)
- {
- return bitSize / 8 - 1;
- }
-
- return bitSize / 8;
+ return (bitSize + 7) / 8 - 1;
}
else
{
* For RSA this is always one byte less than the key size on
* decryption, and the same length as the key size on encryption.
*
- * @return maximum size for an input block.
+ * @return maximum size for an output block.
*/
public int getOutputBlockSize()
{
if (forEncryption)
{
- return ((bitSize - 1) + 7) / 8;
+ return (bitSize + 7) / 8;
}
else
{
- return (bitSize - 7) / 8;
+ return (bitSize + 7) / 8 - 1;
}
}