001 /**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements. See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package org.apache.geronimo.util.asn1.x509;
020
021 import org.apache.geronimo.util.asn1.ASN1Choice;
022 import org.apache.geronimo.util.asn1.ASN1Encodable;
023 import org.apache.geronimo.util.asn1.ASN1OctetString;
024 import org.apache.geronimo.util.asn1.ASN1Sequence;
025 import org.apache.geronimo.util.asn1.ASN1TaggedObject;
026 import org.apache.geronimo.util.asn1.DEREncodable;
027 import org.apache.geronimo.util.asn1.DERIA5String;
028 import org.apache.geronimo.util.asn1.DERObject;
029 import org.apache.geronimo.util.asn1.DERObjectIdentifier;
030 import org.apache.geronimo.util.asn1.DERTaggedObject;
031
032 /**
033 * The GeneralName object.
034 * <pre>
035 * GeneralName ::= CHOICE {
036 * otherName [0] OtherName,
037 * rfc822Name [1] IA5String,
038 * dNSName [2] IA5String,
039 * x400Address [3] ORAddress,
040 * directoryName [4] Name,
041 * ediPartyName [5] EDIPartyName,
042 * uniformResourceIdentifier [6] IA5String,
043 * iPAddress [7] OCTET STRING,
044 * registeredID [8] OBJECT IDENTIFIER}
045 *
046 * OtherName ::= SEQUENCE {
047 * type-id OBJECT IDENTIFIER,
048 * value [0] EXPLICIT ANY DEFINED BY type-id }
049 *
050 * EDIPartyName ::= SEQUENCE {
051 * nameAssigner [0] DirectoryString OPTIONAL,
052 * partyName [1] DirectoryString }
053 *
054 * Name ::= CHOICE { RDNSequence }
055 * </pre>
056 */
057 public class GeneralName
058 extends ASN1Encodable
059 implements ASN1Choice
060 {
061 public static final int otherName = 0;
062 public static final int rfc822Name = 1;
063 public static final int dNSName = 2;
064 public static final int x400Address = 3;
065 public static final int directoryName = 4;
066 public static final int ediPartyName = 5;
067 public static final int uniformResourceIdentifier = 6;
068 public static final int iPAddress = 7;
069 public static final int registeredID = 8;
070
071 DEREncodable obj;
072 int tag;
073
074 public GeneralName(
075 X509Name dirName)
076 {
077 this.obj = dirName;
078 this.tag = 4;
079 }
080
081 /**
082 * @deprecated this constructor seems the wrong way round! Use GeneralName(tag, name).
083 */
084 public GeneralName(
085 DERObject name, int tag)
086 {
087 this.obj = name;
088 this.tag = tag;
089 }
090
091 /**
092 * When the subjectAltName extension contains an Internet mail address,
093 * the address MUST be included as an rfc822Name. The format of an
094 * rfc822Name is an "addr-spec" as defined in RFC 822 [RFC 822].
095 *
096 * When the subjectAltName extension contains a domain name service
097 * label, the domain name MUST be stored in the dNSName (an IA5String).
098 * The name MUST be in the "preferred name syntax," as specified by RFC
099 * 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 }