Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / libjava / classpath / gnu / java / security / x509 / ext / Extension.java
1 /* Extension.java -- an X.509 certificate or CRL extension.
2    Copyright (C) 2004, 2006, 2010  Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package gnu.java.security.x509.ext;
40
41 import gnu.java.security.Configuration;
42 import gnu.java.security.OID;
43 import gnu.java.security.der.DER;
44 import gnu.java.security.der.DERReader;
45 import gnu.java.security.der.DERValue;
46 import gnu.java.security.x509.Util;
47
48 import java.io.IOException;
49 import java.util.ArrayList;
50 import java.util.Arrays;
51 import java.util.List;
52 import java.util.logging.Logger;
53
54 public class Extension
55 {
56   private static final Logger log = Configuration.DEBUG ?
57                         Logger.getLogger(Extension.class.getName()) : null;
58   /**
59    * This extension's object identifier.
60    */
61   protected final OID oid;
62
63   /**
64    * The criticality flag.
65    */
66   protected final boolean critical;
67
68   /**
69    * Whether or not this extension is locally supported.
70    */
71   protected boolean isSupported;
72
73   /**
74    * The extension value.
75    */
76   protected final Value value;
77
78   /**
79    * The DER encoded form.
80    */
81   protected byte[] encoded;
82
83   // Constructors.
84   // -------------------------------------------------------------------------
85
86   public Extension(byte[] encoded) throws IOException
87   {
88     this.encoded = (byte[]) encoded.clone();
89     DERReader der = new DERReader(encoded);
90
91     // Extension ::= SEQUENCE {
92     DERValue val = der.read();
93     if (Configuration.DEBUG)
94       log.fine("read val  tag == " + val.getTag() + " len == " + val.getLength());
95     if (!val.isConstructed())
96       throw new IOException("malformed Extension");
97
98     //   extnID    OBJECT IDENTIFIER,
99     val = der.read();
100     if (val.getTag() != DER.OBJECT_IDENTIFIER)
101       throw new IOException("expecting OBJECT IDENTIFIER");
102     oid = (OID) val.getValue();
103     if (Configuration.DEBUG)
104       log.fine("read oid == " + oid);
105
106     //   critical  BOOLEAN DEFAULT FALSE,
107     val = der.read();
108     if (val.getTag() == DER.BOOLEAN)
109       {
110         critical = ((Boolean) val.getValue()).booleanValue();
111         val = der.read();
112       }
113     else
114       critical = false;
115     if (Configuration.DEBUG)
116       log.fine("is critical == " + critical);
117
118     //   extnValue OCTET STRING }
119     if (val.getTag() != DER.OCTET_STRING)
120       throw new IOException("expecting OCTET STRING");
121     byte[] encval = (byte[]) val.getValue();
122     isSupported = true;
123     if (oid.equals(AuthorityKeyIdentifier.ID))
124       {
125         value = new AuthorityKeyIdentifier(encval);
126       }
127     else if (oid.equals(SubjectKeyIdentifier.ID))
128       {
129         value = new SubjectKeyIdentifier(encval);
130       }
131     else if (oid.equals(KeyUsage.ID))
132       {
133         value = new KeyUsage(encval);
134       }
135     else if (oid.equals(PrivateKeyUsagePeriod.ID))
136       {
137         value = new PrivateKeyUsagePeriod(encval);
138       }
139     else if (oid.equals(CertificatePolicies.ID))
140       {
141         value = new CertificatePolicies(encval);
142       }
143     else if (oid.equals (PolicyConstraint.ID))
144       {
145         value = new PolicyConstraint (encval);
146       }
147     else if (oid.equals(PolicyMappings.ID))
148       {
149         value = new PolicyMappings(encval);
150       }
151     else if (oid.equals(SubjectAlternativeNames.ID))
152       {
153         value = new SubjectAlternativeNames(encval);
154       }
155     else if (oid.equals(IssuerAlternativeNames.ID))
156       {
157         value = new IssuerAlternativeNames(encval);
158       }
159     else if (oid.equals(BasicConstraints.ID))
160       {
161         value = new BasicConstraints(encval);
162       }
163     else if (oid.equals(ExtendedKeyUsage.ID))
164       {
165         value = new ExtendedKeyUsage(encval);
166       }
167     else if (oid.equals(CRLNumber.ID))
168       {
169         value = new CRLNumber(encval);
170       }
171     else if (oid.equals(ReasonCode.ID))
172       {
173         value = new ReasonCode(encval);
174       }
175     else if (oid.equals(NameConstraints.ID))
176       {
177         value = new NameConstraints(encval);
178       }
179     else
180       {
181         value = new Value(encval);
182         isSupported = false;
183       }
184     if (Configuration.DEBUG)
185       log.fine("read value == " + value);
186   }
187
188   public Extension (final OID oid, final Value value, final boolean critical)
189   {
190     this.oid = oid;
191     this.value = value;
192     this.critical = critical;
193     isSupported = true;
194   }
195
196   // Instance methods.
197   // -------------------------------------------------------------------------
198
199   public OID getOid()
200   {
201     return oid;
202   }
203
204   public boolean isCritical()
205   {
206     return critical;
207   }
208
209   public boolean isSupported()
210   {
211     return isSupported;
212   }
213
214   public Value getValue()
215   {
216     return value;
217   }
218
219   public byte[] getEncoded()
220   {
221     if (encoded == null)
222       encode();
223     return (byte[]) encoded.clone();
224   }
225
226   public String toString()
227   {
228     return Extension.class.getName() + " [ id=" + oid + " critical=" +
229       critical + " value=" + value + " ]";
230   }
231
232   public DERValue getDerValue()
233   {
234     List<DERValue> ext = new ArrayList<DERValue>(3);
235     ext.add(new DERValue(DER.OBJECT_IDENTIFIER, oid));
236     ext.add(new DERValue(DER.BOOLEAN, Boolean.valueOf(critical)));
237     ext.add(new DERValue(DER.OCTET_STRING, value.getEncoded()));
238     return new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, ext);
239   }
240
241   // Own methods.
242   // -------------------------------------------------------------------------
243
244   private void encode()
245   {
246     encoded = getDerValue().getEncoded();
247   }
248
249   // Inner class.
250   // -------------------------------------------------------------------------
251
252   public static class Value
253   {
254
255     // Fields.
256     // -----------------------------------------------------------------------
257
258     protected byte[] encoded;
259
260     // Constructor.
261     // -----------------------------------------------------------------------
262
263     public Value(byte[] encoded)
264     {
265       this.encoded = (byte[]) encoded.clone();
266     }
267
268     protected Value() { }
269
270     // Instance methods.
271     // -----------------------------------------------------------------------
272
273     public byte[] getEncoded()
274     {
275       return (byte[]) encoded;
276     }
277
278     public int hashCode()
279     {
280       int result = 0;
281       for (int i = 0; i < encoded.length; ++i)
282         result = result * 31 + encoded[i];
283       return result;
284     }
285
286     public boolean equals(Object o)
287     {
288       if (!(o instanceof Value))
289         return false;
290       return Arrays.equals(encoded, ((Value) o).encoded);
291     }
292
293     public String toString()
294     {
295       return Util.toHexString(encoded, ':');
296     }
297   }
298 }