1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46:
47: import ;
48: import ;
49: import ;
50: import ;
51:
52: public class Extension
53: {
54:
55:
56:
57:
58: private static final boolean DEBUG = false;
59: private static void debug(String msg)
60: {
61: System.err.print(">> Extension: ");
62: System.err.println(msg);
63: }
64:
65:
68: protected final OID oid;
69:
70:
73: protected final boolean critical;
74:
75:
78: protected boolean isSupported;
79:
80:
83: protected final Value value;
84:
85:
88: protected byte[] encoded;
89:
90:
91:
92:
93: public Extension(byte[] encoded) throws IOException
94: {
95: this.encoded = (byte[]) encoded.clone();
96: DERReader der = new DERReader(encoded);
97:
98:
99: DERValue val = der.read();
100: if (DEBUG) debug("read val tag == " + val.getTag() + " len == " + val.getLength());
101: if (!val.isConstructed())
102: throw new IOException("malformed Extension");
103:
104:
105: val = der.read();
106: if (val.getTag() != DER.OBJECT_IDENTIFIER)
107: throw new IOException("expecting OBJECT IDENTIFIER");
108: oid = (OID) val.getValue();
109: if (DEBUG) debug("read oid == " + oid);
110:
111:
112: val = der.read();
113: if (val.getTag() == DER.BOOLEAN)
114: {
115: critical = ((Boolean) val.getValue()).booleanValue();
116: val = der.read();
117: }
118: else
119: critical = false;
120: if (DEBUG) debug("is critical == " + critical);
121:
122:
123: if (val.getTag() != DER.OCTET_STRING)
124: throw new IOException("expecting OCTET STRING");
125: byte[] encval = (byte[]) val.getValue();
126: isSupported = true;
127: if (oid.equals(AuthorityKeyIdentifier.ID))
128: {
129: value = new AuthorityKeyIdentifier(encval);
130: }
131: else if (oid.equals(SubjectKeyIdentifier.ID))
132: {
133: value = new SubjectKeyIdentifier(encval);
134: }
135: else if (oid.equals(KeyUsage.ID))
136: {
137: value = new KeyUsage(encval);
138: }
139: else if (oid.equals(PrivateKeyUsagePeriod.ID))
140: {
141: value = new PrivateKeyUsagePeriod(encval);
142: }
143: else if (oid.equals(CertificatePolicies.ID))
144: {
145: value = new CertificatePolicies(encval);
146: }
147: else if (oid.equals (PolicyConstraint.ID))
148: {
149: value = new PolicyConstraint (encval);
150: }
151: else if (oid.equals(PolicyMappings.ID))
152: {
153: value = new PolicyMappings(encval);
154: }
155: else if (oid.equals(SubjectAlternativeNames.ID))
156: {
157: value = new SubjectAlternativeNames(encval);
158: }
159: else if (oid.equals(IssuerAlternativeNames.ID))
160: {
161: value = new IssuerAlternativeNames(encval);
162: }
163: else if (oid.equals(BasicConstraints.ID))
164: {
165: value = new BasicConstraints(encval);
166: }
167: else if (oid.equals(ExtendedKeyUsage.ID))
168: {
169: value = new ExtendedKeyUsage(encval);
170: }
171: else if (oid.equals(CRLNumber.ID))
172: {
173: value = new CRLNumber(encval);
174: }
175: else if (oid.equals(ReasonCode.ID))
176: {
177: value = new ReasonCode(encval);
178: }
179: else
180: {
181: value = new Value(encval);
182: isSupported = false;
183: }
184: if (DEBUG) debug("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 ext = new ArrayList (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: }