View Javadoc

1   /**
2    *
3    *  Licensed to the Apache Software Foundation (ASF) under one or more
4    *  contributor license agreements.  See the NOTICE file distributed with
5    *  this work for additional information regarding copyright ownership.
6    *  The ASF licenses this file to You under the Apache License, Version 2.0
7    *  (the "License"); you may not use this file except in compliance with
8    *  the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing, software
13   *  distributed under the License is distributed on an "AS IS" BASIS,
14   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *  See the License for the specific language governing permissions and
16   *  limitations under the License.
17   */
18  
19  package org.apache.geronimo.util.asn1.x509;
20  
21  import org.apache.geronimo.util.asn1.ASN1Choice;
22  import org.apache.geronimo.util.asn1.ASN1Encodable;
23  import org.apache.geronimo.util.asn1.ASN1OctetString;
24  import org.apache.geronimo.util.asn1.ASN1Sequence;
25  import org.apache.geronimo.util.asn1.ASN1TaggedObject;
26  import org.apache.geronimo.util.asn1.DEREncodable;
27  import org.apache.geronimo.util.asn1.DERIA5String;
28  import org.apache.geronimo.util.asn1.DERObject;
29  import org.apache.geronimo.util.asn1.DERObjectIdentifier;
30  import org.apache.geronimo.util.asn1.DERTaggedObject;
31  
32  /**
33   * The GeneralName object.
34   * <pre>
35   * GeneralName ::= CHOICE {
36   *      otherName                       [0]     OtherName,
37   *      rfc822Name                      [1]     IA5String,
38   *      dNSName                         [2]     IA5String,
39   *      x400Address                     [3]     ORAddress,
40   *      directoryName                   [4]     Name,
41   *      ediPartyName                    [5]     EDIPartyName,
42   *      uniformResourceIdentifier       [6]     IA5String,
43   *      iPAddress                       [7]     OCTET STRING,
44   *      registeredID                    [8]     OBJECT IDENTIFIER}
45   *
46   * OtherName ::= SEQUENCE {
47   *      type-id    OBJECT IDENTIFIER,
48   *      value      [0] EXPLICIT ANY DEFINED BY type-id }
49   *
50   * EDIPartyName ::= SEQUENCE {
51   *      nameAssigner            [0]     DirectoryString OPTIONAL,
52   *      partyName               [1]     DirectoryString }
53   *
54   * Name ::= CHOICE { RDNSequence }
55   * </pre>
56   */
57  public class GeneralName
58      extends ASN1Encodable
59      implements ASN1Choice
60  {
61      public static final int otherName                     = 0;
62      public static final int rfc822Name                    = 1;
63      public static final int dNSName                       = 2;
64      public static final int x400Address                   = 3;
65      public static final int directoryName                 = 4;
66      public static final int ediPartyName                  = 5;
67      public static final int uniformResourceIdentifier     = 6;
68      public static final int iPAddress                     = 7;
69      public static final int registeredID                  = 8;
70  
71      DEREncodable      obj;
72      int               tag;
73  
74      public GeneralName(
75          X509Name  dirName)
76      {
77          this.obj = dirName;
78          this.tag = 4;
79      }
80  
81      /**
82       * @deprecated this constructor seems the wrong way round! Use GeneralName(tag, name).
83       */
84      public GeneralName(
85          DERObject name, int tag)
86      {
87          this.obj = name;
88          this.tag = tag;
89      }
90  
91      /**
92       * When the subjectAltName extension contains an Internet mail address,
93       * the address MUST be included as an rfc822Name. The format of an
94       * rfc822Name is an "addr-spec" as defined in RFC 822 [RFC 822].
95       *
96       * When the subjectAltName extension contains a domain name service
97       * label, the domain name MUST be stored in the dNSName (an IA5String).
98       * The name MUST be in the "preferred name syntax," as specified by RFC
99       * 1034 [RFC 1034].
100      *
101      * When the subjectAltName extension contains a URI, the name MUST be
102      * stored in the uniformResourceIdentifier (an IA5String). The name MUST
103      * be a non-relative URL, and MUST follow the URL syntax and encoding
104      * rules specified in [RFC 1738].  The name must include both a scheme
105      * (e.g., "http" or "ftp") and a scheme-specific-part.  The scheme-
106      * specific-part must include a fully qualified domain name or IP
107      * address as the host.
108      *
109      * When the subjectAltName extension contains a iPAddress, the address
110      * MUST be stored in the octet string in "network byte order," as
111      * specified in RFC 791 [RFC 791]. The least significant bit (LSB) of
112      * each octet is the LSB of the corresponding byte in the network
113      * address. For IP Version 4, as specified in RFC 791, the octet string
114      * MUST contain exactly four octets.  For IP Version 6, as specified in
115      * RFC 1883, the octet string MUST contain exactly sixteen octets [RFC
116      * 1883].
117      */
118     public GeneralName(
119         int           tag,
120         ASN1Encodable name)
121     {
122         this.obj = name;
123         this.tag = tag;
124     }
125 
126     /**
127      * Create a General name for the given tag from the passed in String.
128      *
129      * @param tag tag number
130      * @param name string representation of name
131      */
132     public GeneralName(
133         int       tag,
134         String    name)
135     {
136         if (tag == rfc822Name || tag == dNSName || tag == uniformResourceIdentifier)
137         {
138             this.tag = tag;
139             this.obj = new DERIA5String(name);
140         }
141         else if (tag == registeredID)
142         {
143             this.tag = tag;
144             this.obj = new DERObjectIdentifier(name);
145         }
146         else
147         {
148             throw new IllegalArgumentException("can't process String for tag: " + tag);
149         }
150     }
151 
152     public static GeneralName getInstance(
153         Object obj)
154     {
155         if (obj == null || obj instanceof GeneralName)
156         {
157             return (GeneralName)obj;
158         }
159 
160         if (obj instanceof ASN1TaggedObject)
161         {
162             ASN1TaggedObject    tagObj = (ASN1TaggedObject)obj;
163             int                 tag = tagObj.getTagNo();
164 
165             switch (tag)
166             {
167             case otherName:
168                 return new GeneralName(ASN1Sequence.getInstance(tagObj, false), tag);
169             case rfc822Name:
170                 return new GeneralName(DERIA5String.getInstance(tagObj, false), tag);
171             case dNSName:
172                 return new GeneralName(DERIA5String.getInstance(tagObj, false), tag);
173             case x400Address:
174                 throw new IllegalArgumentException("unknown tag: " + tag);
175             case directoryName:
176                 return new GeneralName(ASN1Sequence.getInstance(tagObj, true), tag);
177             case ediPartyName:
178                 return new GeneralName(ASN1Sequence.getInstance(tagObj, false), tag);
179             case uniformResourceIdentifier:
180                 return new GeneralName(DERIA5String.getInstance(tagObj, false), tag);
181             case iPAddress:
182                 return new GeneralName(ASN1OctetString.getInstance(tagObj, false), tag);
183             case registeredID:
184                 return new GeneralName(DERObjectIdentifier.getInstance(tagObj, false), tag);
185             }
186         }
187 
188         throw new IllegalArgumentException("unknown object in getInstance");
189     }
190 
191     public static GeneralName getInstance(
192         ASN1TaggedObject tagObj,
193         boolean          explicit)
194     {
195         return GeneralName.getInstance(ASN1TaggedObject.getInstance(tagObj, true));
196     }
197 
198     public int getTagNo()
199     {
200         return tag;
201     }
202 
203     public DEREncodable getName()
204     {
205         return obj;
206     }
207 
208     public DERObject toASN1Object()
209     {
210         if (tag == directoryName)       // directoryName is explicitly tagged as it is a CHOICE
211         {
212             return new DERTaggedObject(true, tag, obj);
213         }
214         else
215         {
216             return new DERTaggedObject(false, tag, obj);
217         }
218     }
219 }