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
175: {
176: value = new Value(encval);
177: isSupported = false;
178: }
179: if (Configuration.DEBUG)
180: log.fine("read value == " + value);
181: }
182:
183: public Extension (final OID oid, final Value value, final boolean critical)
184: {
185: this.oid = oid;
186: this.value = value;
187: this.critical = critical;
188: isSupported = true;
189: }
190:
191:
192:
193:
194: public OID getOid()
195: {
196: return oid;
197: }
198:
199: public boolean isCritical()
200: {
201: return critical;
202: }
203:
204: public boolean isSupported()
205: {
206: return isSupported;
207: }
208:
209: public Value getValue()
210: {
211: return value;
212: }
213:
214: public byte[] getEncoded()
215: {
216: if (encoded == null)
217: encode();
218: return (byte[]) encoded.clone();
219: }
220:
221: public String toString()
222: {
223: return Extension.class.getName() + " [ id=" + oid + " critical=" +
224: critical + " value=" + value + " ]";
225: }
226:
227: public DERValue getDerValue()
228: {
229: List ext = new ArrayList (3);
230: ext.add (new DERValue (DER.OBJECT_IDENTIFIER, oid));
231: ext.add (new DERValue (DER.BOOLEAN, Boolean.valueOf (critical)));
232: ext.add (new DERValue (DER.OCTET_STRING, value.getEncoded()));
233: return new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, ext);
234: }
235:
236:
237:
238:
239: private void encode()
240: {
241: encoded = getDerValue().getEncoded();
242: }
243:
244:
245:
246:
247: public static class Value
248: {
249:
250:
251:
252:
253: protected byte[] encoded;
254:
255:
256:
257:
258: public Value(byte[] encoded)
259: {
260: this.encoded = (byte[]) encoded.clone();
261: }
262:
263: protected Value() { }
264:
265:
266:
267:
268: public byte[] getEncoded()
269: {
270: return (byte[]) encoded;
271: }
272:
273: public int hashCode()
274: {
275: int result = 0;
276: for (int i = 0; i < encoded.length; ++i)
277: result = result * 31 + encoded[i];
278: return result;
279: }
280:
281: public boolean equals(Object o)
282: {
283: if (!(o instanceof Value))
284: return false;
285: return Arrays.equals(encoded, ((Value) o).encoded);
286: }
287:
288: public String toString()
289: {
290: return Util.toHexString(encoded, ':');
291: }
292: }
293: }