001package org.apache.commons.ssl.org.bouncycastle.asn1.x509; 002 003import java.math.BigInteger; 004 005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Boolean; 006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector; 007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Integer; 008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object; 009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive; 010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence; 011import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject; 012import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence; 013 014public class BasicConstraints 015 extends ASN1Object 016{ 017 ASN1Boolean cA = ASN1Boolean.getInstance(false); 018 ASN1Integer pathLenConstraint = null; 019 020 public static BasicConstraints getInstance( 021 ASN1TaggedObject obj, 022 boolean explicit) 023 { 024 return getInstance(ASN1Sequence.getInstance(obj, explicit)); 025 } 026 027 public static BasicConstraints getInstance( 028 Object obj) 029 { 030 if (obj instanceof BasicConstraints) 031 { 032 return (BasicConstraints)obj; 033 } 034 if (obj instanceof X509Extension) 035 { 036 return getInstance(X509Extension.convertValueToObject((X509Extension)obj)); 037 } 038 if (obj != null) 039 { 040 return new BasicConstraints(ASN1Sequence.getInstance(obj)); 041 } 042 043 return null; 044 } 045 046 public static BasicConstraints fromExtensions(Extensions extensions) 047 { 048 return BasicConstraints.getInstance(extensions.getExtensionParsedValue(Extension.basicConstraints)); 049 } 050 051 private BasicConstraints( 052 ASN1Sequence seq) 053 { 054 if (seq.size() == 0) 055 { 056 this.cA = null; 057 this.pathLenConstraint = null; 058 } 059 else 060 { 061 if (seq.getObjectAt(0) instanceof ASN1Boolean) 062 { 063 this.cA = ASN1Boolean.getInstance(seq.getObjectAt(0)); 064 } 065 else 066 { 067 this.cA = null; 068 this.pathLenConstraint = ASN1Integer.getInstance(seq.getObjectAt(0)); 069 } 070 if (seq.size() > 1) 071 { 072 if (this.cA != null) 073 { 074 this.pathLenConstraint = ASN1Integer.getInstance(seq.getObjectAt(1)); 075 } 076 else 077 { 078 throw new IllegalArgumentException("wrong sequence in constructor"); 079 } 080 } 081 } 082 } 083 084 public BasicConstraints( 085 boolean cA) 086 { 087 if (cA) 088 { 089 this.cA = ASN1Boolean.getInstance(true); 090 } 091 else 092 { 093 this.cA = null; 094 } 095 this.pathLenConstraint = null; 096 } 097 098 /** 099 * create a cA=true object for the given path length constraint. 100 * 101 * @param pathLenConstraint 102 */ 103 public BasicConstraints( 104 int pathLenConstraint) 105 { 106 this.cA = ASN1Boolean.getInstance(true); 107 this.pathLenConstraint = new ASN1Integer(pathLenConstraint); 108 } 109 110 public boolean isCA() 111 { 112 return (cA != null) && cA.isTrue(); 113 } 114 115 public BigInteger getPathLenConstraint() 116 { 117 if (pathLenConstraint != null) 118 { 119 return pathLenConstraint.getValue(); 120 } 121 122 return null; 123 } 124 125 /** 126 * Produce an object suitable for an ASN1OutputStream. 127 * <pre> 128 * BasicConstraints := SEQUENCE { 129 * cA BOOLEAN DEFAULT FALSE, 130 * pathLenConstraint INTEGER (0..MAX) OPTIONAL 131 * } 132 * </pre> 133 */ 134 public ASN1Primitive toASN1Primitive() 135 { 136 ASN1EncodableVector v = new ASN1EncodableVector(); 137 138 if (cA != null) 139 { 140 v.add(cA); 141 } 142 143 if (pathLenConstraint != null) // yes some people actually do this when cA is false... 144 { 145 v.add(pathLenConstraint); 146 } 147 148 return new DERSequence(v); 149 } 150 151 public String toString() 152 { 153 if (pathLenConstraint == null) 154 { 155 if (cA == null) 156 { 157 return "BasicConstraints: isCa(false)"; 158 } 159 return "BasicConstraints: isCa(" + this.isCA() + ")"; 160 } 161 return "BasicConstraints: isCa(" + this.isCA() + "), pathLenConstraint = " + pathLenConstraint.getValue(); 162 } 163}