1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47:
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53:
54: public class Extension
55: {
56: private static final Logger log = Logger.getLogger(Extension.class.getName());
57:
60: protected final OID oid;
61:
62:
65: protected final boolean critical;
66:
67:
70: protected boolean isSupported;
71:
72:
75: protected final Value value;
76:
77:
80: protected byte[] encoded;
81:
82:
83:
84:
85: public Extension(byte[] encoded) throws IOException
86: {
87: this.encoded = (byte[]) encoded.clone();
88: DERReader der = new DERReader(encoded);
89:
90:
91: DERValue val = der.read();
92: if (Configuration.DEBUG)
93: log.fine("read val tag == " + val.getTag() + " len == " + val.getLength());
94: if (!val.isConstructed())
95: throw new IOException("malformed Extension");
96:
97:
98: val = der.read();
99: if (val.getTag() != DER.OBJECT_IDENTIFIER)
100: throw new IOException("expecting OBJECT IDENTIFIER");
101: oid = (OID) val.getValue();
102: if (Configuration.DEBUG)
103: log.fine("read oid == " + oid);
104:
105:
106: val = der.read();
107: if (val.getTag() == DER.BOOLEAN)
108: {
109: critical = ((Boolean) val.getValue()).booleanValue();
110: val = der.read();
111: }
112: else
113: critical = false;
114: if (Configuration.DEBUG)
115: log.fine("is critical == " + critical);
116:
117:
118: if (val.getTag() != DER.OCTET_STRING)
119: throw new IOException("expecting OCTET STRING");
120: byte[] encval = (byte[]) val.getValue();
121: isSupported = true;
122: if (oid.equals(AuthorityKeyIdentifier.ID))
123: {
124: value = new AuthorityKeyIdentifier(encval);
125: }
126: else if (oid.equals(SubjectKeyIdentifier.ID))
127: {
128: value = new SubjectKeyIdentifier(encval);
129: }
130: else if (oid.equals(KeyUsage.ID))
131: {
132: value = new KeyUsage(encval);
133: }
134: else if (oid.equals(PrivateKeyUsagePeriod.ID))
135: {
136: value = new PrivateKeyUsagePeriod(encval);
137: }
138: else if (oid.equals(CertificatePolicies.ID))
139: {
140: value = new CertificatePolicies(encval);
141: }
142: else if (oid.equals (PolicyConstraint.ID))
143: {
144: value = new PolicyConstraint (encval);
145: }
146: else if (oid.equals(PolicyMappings.ID))
147: {
148: value = new PolicyMappings(encval);
149: }
150: else if (oid.equals(SubjectAlternativeNames.ID))
151: {
152: value = new SubjectAlternativeNames(encval);
153: }
154: else if (oid.equals(IssuerAlternativeNames.ID))
155: {
156: value = new IssuerAlternativeNames(encval);
157: }
158: else if (oid.equals(BasicConstraints.ID))
159: {
160: value = new BasicConstraints(encval);
161: }
162: else if (oid.equals(ExtendedKeyUsage.ID))
163: {
164: value = new ExtendedKeyUsage(encval);
165: }
166: else if (oid.equals(CRLNumber.ID))
167: {
168: value = new CRLNumber(encval);
169: }
170: else if (oid.equals(ReasonCode.ID))
171: {
172: value = new ReasonCode(encval);
173: }
174: else if (oid.equals(NameConstraints.ID))
175: {
176: value = new NameConstraints(encval);
177: }
178: else
179: {
180: value = new Value(encval);
181: isSupported = false;
182: }
183: if (Configuration.DEBUG)
184: log.fine("read value == " + value);
185: }
186:
187: public Extension (final OID oid, final Value value, final boolean critical)
188: {
189: this.oid = oid;
190: this.value = value;
191: this.critical = critical;
192: isSupported = true;
193: }
194:
195:
196:
197:
198: public OID getOid()
199: {
200: return oid;
201: }
202:
203: public boolean isCritical()
204: {
205: return critical;
206: }
207:
208: public boolean isSupported()
209: {
210: return isSupported;
211: }
212:
213: public Value getValue()
214: {
215: return value;
216: }
217:
218: public byte[] getEncoded()
219: {
220: if (encoded == null)
221: encode();
222: return (byte[]) encoded.clone();
223: }
224:
225: public String toString()
226: {
227: return Extension.class.getName() + " [ id=" + oid + " critical=" +
228: critical + " value=" + value + " ]";
229: }
230:
231: public DERValue getDerValue()
232: {
233: List<DERValue> ext = new ArrayList<DERValue>(3);
234: ext.add(new DERValue(DER.OBJECT_IDENTIFIER, oid));
235: ext.add(new DERValue(DER.BOOLEAN, Boolean.valueOf(critical)));
236: ext.add(new DERValue(DER.OCTET_STRING, value.getEncoded()));
237: return new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, ext);
238: }
239:
240:
241:
242:
243: private void encode()
244: {
245: encoded = getDerValue().getEncoded();
246: }
247:
248:
249:
250:
251: public static class Value
252: {
253:
254:
255:
256:
257: protected byte[] encoded;
258:
259:
260:
261:
262: public Value(byte[] encoded)
263: {
264: this.encoded = (byte[]) encoded.clone();
265: }
266:
267: protected Value() { }
268:
269:
270:
271:
272: public byte[] getEncoded()
273: {
274: return (byte[]) encoded;
275: }
276:
277: public int hashCode()
278: {
279: int result = 0;
280: for (int i = 0; i < encoded.length; ++i)
281: result = result * 31 + encoded[i];
282: return result;
283: }
284:
285: public boolean equals(Object o)
286: {
287: if (!(o instanceof Value))
288: return false;
289: return Arrays.equals(encoded, ((Value) o).encoded);
290: }
291:
292: public String toString()
293: {
294: return Util.toHexString(encoded, ':');
295: }
296: }
297: }