001: package org.bouncycastle.asn1.x509;
002:
003: import org.bouncycastle.asn1.ASN1Encodable;
004: import org.bouncycastle.asn1.ASN1EncodableVector;
005: import org.bouncycastle.asn1.ASN1Sequence;
006: import org.bouncycastle.asn1.ASN1TaggedObject;
007: import org.bouncycastle.asn1.DERInteger;
008: import org.bouncycastle.asn1.DERObject;
009: import org.bouncycastle.asn1.DERSequence;
010: import org.bouncycastle.asn1.DERTaggedObject;
011:
012: import java.math.BigInteger;
013:
014: /**
015: * Class for containing a restriction object subtrees in NameConstraints. See
016: * RFC 3280.
017: *
018: * <pre>
019: *
020: * GeneralSubtree ::= SEQUENCE
021: * {
022: * base GeneralName,
023: * minimum [0] BaseDistance DEFAULT 0,
024: * maximum [1] BaseDistance OPTIONAL
025: * }
026: * </pre>
027: *
028: * @see org.bouncycastle.asn1.x509.NameConstraints
029: *
030: */
031: public class GeneralSubtree extends ASN1Encodable {
032: private static final BigInteger ZERO = BigInteger.valueOf(0);
033:
034: private GeneralName base;
035:
036: private DERInteger minimum;
037:
038: private DERInteger maximum;
039:
040: public GeneralSubtree(ASN1Sequence seq) {
041: base = GeneralName.getInstance(seq.getObjectAt(0));
042:
043: switch (seq.size()) {
044: case 1:
045: break;
046: case 2:
047: ASN1TaggedObject o = ASN1TaggedObject.getInstance(seq
048: .getObjectAt(1));
049: switch (o.getTagNo()) {
050: case 0:
051: minimum = DERInteger.getInstance(o, false);
052: break;
053: case 1:
054: maximum = DERInteger.getInstance(o, false);
055: break;
056: default:
057: throw new IllegalArgumentException("Bad tag number: "
058: + o.getTagNo());
059: }
060: break;
061: case 3:
062: minimum = DERInteger.getInstance(ASN1TaggedObject
063: .getInstance(seq.getObjectAt(1)));
064: maximum = DERInteger.getInstance(ASN1TaggedObject
065: .getInstance(seq.getObjectAt(2)));
066: break;
067: default:
068: throw new IllegalArgumentException("Bad sequence size: "
069: + seq.size());
070: }
071: }
072:
073: /**
074: * Constructor from a given details.
075: *
076: * According RFC 3280, the minimum and maximum fields are not used with any
077: * name forms, thus minimum MUST be zero, and maximum MUST be absent.
078: * <p>
079: * If minimum is <code>null</code>, zero is assumed, if
080: * maximum is <code>null</code>, maximum is absent.
081: *
082: * @param base
083: * A restriction.
084: * @param minimum
085: * Minimum
086: *
087: * @param maximum
088: * Maximum
089: */
090: public GeneralSubtree(GeneralName base, BigInteger minimum,
091: BigInteger maximum) {
092: this .base = base;
093: if (maximum != null) {
094: this .maximum = new DERInteger(maximum);
095: }
096: if (minimum == null) {
097: this .minimum = null;
098: } else {
099: this .minimum = new DERInteger(minimum);
100: }
101: }
102:
103: public GeneralSubtree(GeneralName base) {
104: this (base, null, null);
105: }
106:
107: public static GeneralSubtree getInstance(ASN1TaggedObject o,
108: boolean explicit) {
109: return new GeneralSubtree(ASN1Sequence.getInstance(o, explicit));
110: }
111:
112: public static GeneralSubtree getInstance(Object obj) {
113: if (obj == null) {
114: return null;
115: }
116:
117: if (obj instanceof GeneralSubtree) {
118: return (GeneralSubtree) obj;
119: }
120:
121: return new GeneralSubtree(ASN1Sequence.getInstance(obj));
122: }
123:
124: public GeneralName getBase() {
125: return base;
126: }
127:
128: public BigInteger getMinimum() {
129: if (minimum == null) {
130: return ZERO;
131: }
132:
133: return minimum.getValue();
134: }
135:
136: public BigInteger getMaximum() {
137: if (maximum == null) {
138: return null;
139: }
140:
141: return maximum.getValue();
142: }
143:
144: /**
145: * Produce an object suitable for an ASN1OutputStream.
146: *
147: * Returns:
148: *
149: * <pre>
150: * GeneralSubtree ::= SEQUENCE
151: * {
152: * base GeneralName,
153: * minimum [0] BaseDistance DEFAULT 0,
154: * maximum [1] BaseDistance OPTIONAL
155: * }
156: * </pre>
157: *
158: * @return a DERObject
159: */
160: public DERObject toASN1Object() {
161: ASN1EncodableVector v = new ASN1EncodableVector();
162:
163: v.add(base);
164:
165: if (minimum != null && !minimum.getValue().equals(ZERO)) {
166: v.add(new DERTaggedObject(false, 0, minimum));
167: }
168:
169: if (maximum != null) {
170: v.add(new DERTaggedObject(false, 1, maximum));
171: }
172:
173: return new DERSequence(v);
174: }
175: }
|