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.DERBoolean;
008: import org.bouncycastle.asn1.DERInteger;
009: import org.bouncycastle.asn1.DERObject;
010: import org.bouncycastle.asn1.DERSequence;
011:
012: import java.math.BigInteger;
013:
014: public class BasicConstraints extends ASN1Encodable {
015: DERBoolean cA = new DERBoolean(false);
016: DERInteger pathLenConstraint = null;
017:
018: public static BasicConstraints getInstance(ASN1TaggedObject obj,
019: boolean explicit) {
020: return getInstance(ASN1Sequence.getInstance(obj, explicit));
021: }
022:
023: public static BasicConstraints getInstance(Object obj) {
024: if (obj == null || obj instanceof BasicConstraints) {
025: return (BasicConstraints) obj;
026: }
027:
028: if (obj instanceof ASN1Sequence) {
029: return new BasicConstraints((ASN1Sequence) obj);
030: }
031:
032: if (obj instanceof X509Extension) {
033: return getInstance(X509Extension
034: .convertValueToObject((X509Extension) obj));
035: }
036:
037: throw new IllegalArgumentException("unknown object in factory");
038: }
039:
040: public BasicConstraints(ASN1Sequence seq) {
041: if (seq.size() == 0) {
042: this .cA = null;
043: this .pathLenConstraint = null;
044: } else {
045: if (seq.getObjectAt(0) instanceof DERBoolean) {
046: this .cA = DERBoolean.getInstance(seq.getObjectAt(0));
047: } else {
048: this .cA = null;
049: this .pathLenConstraint = DERInteger.getInstance(seq
050: .getObjectAt(0));
051: }
052: if (seq.size() > 1) {
053: if (this .cA != null) {
054: this .pathLenConstraint = DERInteger.getInstance(seq
055: .getObjectAt(1));
056: } else {
057: throw new IllegalArgumentException(
058: "wrong sequence in constructor");
059: }
060: }
061: }
062: }
063:
064: /**
065: * @deprecated use one of the other two unambigous constructors.
066: * @param cA
067: * @param pathLenConstraint
068: */
069: public BasicConstraints(boolean cA, int pathLenConstraint) {
070: if (cA) {
071: this .cA = new DERBoolean(cA);
072: this .pathLenConstraint = new DERInteger(pathLenConstraint);
073: } else {
074: this .cA = null;
075: this .pathLenConstraint = null;
076: }
077: }
078:
079: public BasicConstraints(boolean cA) {
080: if (cA) {
081: this .cA = new DERBoolean(true);
082: } else {
083: this .cA = null;
084: }
085: this .pathLenConstraint = null;
086: }
087:
088: /**
089: * create a cA=true object for the given path length constraint.
090: *
091: * @param pathLenConstraint
092: */
093: public BasicConstraints(int pathLenConstraint) {
094: this .cA = new DERBoolean(true);
095: this .pathLenConstraint = new DERInteger(pathLenConstraint);
096: }
097:
098: public boolean isCA() {
099: return (cA != null) && cA.isTrue();
100: }
101:
102: public BigInteger getPathLenConstraint() {
103: if (pathLenConstraint != null) {
104: return pathLenConstraint.getValue();
105: }
106:
107: return null;
108: }
109:
110: /**
111: * Produce an object suitable for an ASN1OutputStream.
112: * <pre>
113: * BasicConstraints := SEQUENCE {
114: * cA BOOLEAN DEFAULT FALSE,
115: * pathLenConstraint INTEGER (0..MAX) OPTIONAL
116: * }
117: * </pre>
118: */
119: public DERObject toASN1Object() {
120: ASN1EncodableVector v = new ASN1EncodableVector();
121:
122: if (cA != null) {
123: v.add(cA);
124: }
125:
126: if (pathLenConstraint != null) // yes some people actually do this when cA is false...
127: {
128: v.add(pathLenConstraint);
129: }
130:
131: return new DERSequence(v);
132: }
133:
134: public String toString() {
135: if (pathLenConstraint == null) {
136: if (cA == null) {
137: return "BasicConstraints: isCa(false)";
138: }
139: return "BasicConstraints: isCa(" + this .isCA() + ")";
140: }
141: return "BasicConstraints: isCa(" + this .isCA()
142: + "), pathLenConstraint = "
143: + pathLenConstraint.getValue();
144: }
145: }
|