org.bouncycastle.oer.OERDefinition Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bcutil-jdk15on Show documentation
Show all versions of bcutil-jdk15on Show documentation
The Bouncy Castle Java APIs for ASN.1 extension and utility APIs used to support bcpkix and bctls. This jar contains APIs for JDK 1.5 and up.
The newest version!
package org.bouncycastle.oer;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Integer;
public class OERDefinition
{
private static final BigInteger[] uIntMax = new BigInteger[]{
new BigInteger("256"),
new BigInteger("65536"),
new BigInteger("4294967296"),
new BigInteger("18446744073709551616"),
};
private static final BigInteger[][] sIntRange = new BigInteger[][]{
new BigInteger[]{new BigInteger("-128"), new BigInteger("127")},
new BigInteger[]{new BigInteger("-32768"), new BigInteger("32767")},
new BigInteger[]{new BigInteger("-2147483648"), new BigInteger("2147483647")},
new BigInteger[]{new BigInteger("-9223372036854775808"), new BigInteger("9223372036854775807")},
};
public enum BaseType
{
SEQ, SEQ_OF, CHOICE, ENUM, INT, OCTET_STRING,
UTF8_STRING, BIT_STRING, NULL, EXTENSION, ENUM_ITEM, BOOLEAN, IS0646String, PrintableString, NumericString,
BMPString, UniversalString, IA5String, VisibleString
}
public static class Element
{
public final BaseType baseType;
public final List children;
public final boolean explicit;
public final String label;
private List optionalChildrenInOrder;
public final BigInteger lowerBound;
public final BigInteger upperBound;
public final boolean extensionsInDefinition;
public final BigInteger enumValue;
public final ASN1Encodable defaultValue;
public Element(
BaseType baseType,
List children,
boolean explicit,
String label,
BigInteger lowerBound,
BigInteger upperBound,
boolean extensionsInDefinition,
BigInteger enumValue, ASN1Encodable defaultValue)
{
this.baseType = baseType;
this.children = children;
this.explicit = explicit;
this.label = label;
this.lowerBound = lowerBound;
this.upperBound = upperBound;
this.extensionsInDefinition = extensionsInDefinition;
this.enumValue = enumValue;
this.defaultValue = defaultValue;
}
public String rangeExpression()
{
return "(" + (lowerBound != null ? lowerBound.toString() : "MIN") + " ... "
+ (upperBound != null ? upperBound.toString() : "MAX") + ")";
}
public String appendLabel(String s)
{
return "[" + (label == null ? "" : label) + (explicit ? " (E)" : "") + "] " + s;
}
public List optionalOrDefaultChildrenInOrder()
{
synchronized (this)
{
// do it once, these definitions can be shared about.
if (optionalChildrenInOrder == null)
{
ArrayList optList = new ArrayList();
for (Iterator it = children.iterator(); it.hasNext();)
{
Element e = (Element)it.next();
if (!e.explicit || e.getDefaultValue() != null)
{
optList.add(e);
}
}
optionalChildrenInOrder = Collections.unmodifiableList(optList);
}
return optionalChildrenInOrder;
}
}
public boolean isUnbounded()
{
return upperBound == null && lowerBound == null;
}
public boolean isLowerRangeZero()
{
return BigInteger.ZERO.equals(lowerBound);
}
/**
* Return true in cases where the range is all positive (0 .. 10)
*
* @return true if condition met.
*/
public boolean isUnsignedWithRange()
{
return isLowerRangeZero() && (upperBound != null && BigInteger.ZERO.compareTo(upperBound) < 0);
}
// True for cases where there is no lower bound or lower bound is less than zero.
public boolean canBeNegative()
{
return lowerBound != null && BigInteger.ZERO.compareTo(lowerBound) > 0;
}
/**
* Determine the number of integer bytes for a range, ints, signed or unsigned that can fit into 1 to 8 octets
* use a fixed with encoding.
* Returns a negative number if the value is signed and the absolute value is the number of bytes.
*/
public int intBytesForRange()
{
if (lowerBound != null && upperBound != null)
{
if (BigInteger.ZERO.equals(lowerBound))
{
//
// Positive range.
//
for (int i = 0, j = 1; i < uIntMax.length; i++, j *= 2)
{
if (upperBound.compareTo(uIntMax[i]) < 0)
{
return j;
}
}
}
else
{
for (int i = 0, j = 1; i < sIntRange.length; i++, j *= 2)
{
if (lowerBound.compareTo(sIntRange[i][0]) >= 0 && upperBound.compareTo(sIntRange[i][1]) < 0)
{
return -j;
}
}
}
}
return 0;
}
public boolean hasPopulatedExtension()
{
for (Iterator it = children.iterator(); it.hasNext();)
{
Element child = (Element)it.next();
if (child.baseType == BaseType.EXTENSION)
{
return true;
}
}
return false;
}
public boolean hasDefaultChildren()
{
for (Iterator it = children.iterator(); it.hasNext();)
{
Element child = (Element)it.next();
if (child.defaultValue != null)
{
return true;
}
}
return false;
}
public ASN1Encodable getDefaultValue()
{
return defaultValue;
}
public Element getFirstChid()
{
return children.get(0);
}
public boolean isFixedLength()
{
return lowerBound != null && (lowerBound.equals(upperBound));
}
}
public static Builder integer()
{
return new Builder(BaseType.INT);
}
public static Builder integer(long val)
{
return new Builder(BaseType.INT).defaultValue(new ASN1Integer(val));
}
public static Builder bitString(long len)
{
return new Builder(BaseType.BIT_STRING).fixedSize(len);
}
public static Builder integer(BigInteger lower, BigInteger upper)
{
return new Builder(BaseType.INT).range(lower, upper);
}
public static Builder integer(long lower, long upper)
{
return new Builder(BaseType.INT).range(BigInteger.valueOf(lower), BigInteger.valueOf(upper));
}
public static Builder integer(long lower, long upper, ASN1Encodable defaultValue)
{
return new Builder(BaseType.INT).range(lower, upper, defaultValue);
}
public static Builder nullValue()
{
return new Builder(BaseType.NULL);
}
public static Builder seq()
{
return new Builder(BaseType.SEQ);
}
public static Builder seq(Object... items)
{
return new Builder(BaseType.SEQ).items(items);
}
public static Builder enumItem(String label)
{
return new Builder(BaseType.ENUM_ITEM).label(label);
}
public static Builder enumItem(String label, BigInteger value)
{
return new Builder(BaseType.ENUM_ITEM).enumValue(value).label(label);
}
public static Builder enumeration(Object... items)
{
return new Builder(BaseType.ENUM).items(items);
}
public static Builder choice(Object... items)
{
return new Builder(BaseType.CHOICE).items(items);
}
public static Builder placeholder()
{
return new Builder(null);
}
public static Builder seqof(Object... items)
{
return new Builder(BaseType.SEQ_OF).items(items);
}
public static Builder octets()
{
return new Builder(BaseType.OCTET_STRING).unbounded();
}
public static Builder octets(int size)
{
return new Builder(BaseType.OCTET_STRING).fixedSize(size);
}
public static Builder octets(int lowerBound, int upperBound)
{
return new Builder(BaseType.OCTET_STRING).range(BigInteger.valueOf(lowerBound), BigInteger.valueOf(upperBound));
}
public static Builder utf8String()
{
return new Builder(BaseType.UTF8_STRING);
}
public static Builder utf8String(int size)
{
return new Builder(BaseType.UTF8_STRING).rangeToMAXFrom(size);
}
public static Builder utf8String(int lowerBound, int upperBound)
{
return new Builder(BaseType.UTF8_STRING).range(BigInteger.valueOf(lowerBound), BigInteger.valueOf(upperBound));
}
public static Builder opaque()
{
return new Builder(BaseType.OCTET_STRING).unbounded();
}
public static List