001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.util.asn1.x509;
019
020 import org.apache.geronimo.util.asn1.ASN1Choice;
021 import org.apache.geronimo.util.asn1.ASN1Encodable;
022 import org.apache.geronimo.util.asn1.ASN1OctetString;
023 import org.apache.geronimo.util.asn1.ASN1Sequence;
024 import org.apache.geronimo.util.asn1.ASN1TaggedObject;
025 import org.apache.geronimo.util.asn1.DEREncodable;
026 import org.apache.geronimo.util.asn1.DERIA5String;
027 import org.apache.geronimo.util.asn1.DERObject;
028 import org.apache.geronimo.util.asn1.DERObjectIdentifier;
029 import org.apache.geronimo.util.asn1.DERTaggedObject;
030
031 /**
032 * The GeneralName object.
033 * <pre>
034 * GeneralName ::= CHOICE {
035 * otherName [0] OtherName,
036 * rfc822Name [1] IA5String,
037 * dNSName [2] IA5String,
038 * x400Address [3] ORAddress,
039 * directoryName [4] Name,
040 * ediPartyName [5] EDIPartyName,
041 * uniformResourceIdentifier [6] IA5String,
042 * iPAddress [7] OCTET STRING,
043 * registeredID [8] OBJECT IDENTIFIER}
044 *
045 * OtherName ::= SEQUENCE {
046 * type-id OBJECT IDENTIFIER,
047 * value [0] EXPLICIT ANY DEFINED BY type-id }
048 *
049 * EDIPartyName ::= SEQUENCE {
050 * nameAssigner [0] DirectoryString OPTIONAL,
051 * partyName [1] DirectoryString }
052 *
053 * Name ::= CHOICE { RDNSequence }
054 * </pre>
055 */
056 public class GeneralName
057 extends ASN1Encodable
058 implements ASN1Choice
059 {
060 public static final int otherName = 0;
061 public static final int rfc822Name = 1;
062 public static final int dNSName = 2;
063 public static final int x400Address = 3;
064 public static final int directoryName = 4;
065 public static final int ediPartyName = 5;
066 public static final int uniformResourceIdentifier = 6;
067 public static final int iPAddress = 7;
068 public static final int registeredID = 8;
069
070 DEREncodable obj;
071 int tag;
072
073 public GeneralName(
074 X509Name dirName)
075 {
076 this.obj = dirName;
077 this.tag = 4;
078 }
079
080 /**
081 * @deprecated this constructor seems the wrong way round! Use GeneralName(tag, name).
082 */
083 public GeneralName(
084 DERObject name, int tag)
085 {
086 this.obj = name;
087 this.tag = tag;
088 }
089
090 /**
091 * When the subjectAltName extension contains an Internet mail address,
092 * the address MUST be included as an rfc822Name. The format of an
093 * rfc822Name is an "addr-spec" as defined in RFC 822 [RFC 822].
094 *
095 * When the subjectAltName extension contains a domain name service
096 * label, the domain name MUST be stored in the dNSName (an IA5String).
097 * The name MUST be in the "preferred name syntax," as specified by RFC
098 * 1034 [RFC 1034].
099 *
100 * When the subjectAltName extension contains a URI, the name MUST be
101 * stored in the uniformResourceIdentifier (an IA5String). The name MUST
102 * be a non-relative URL, and MUST follow the URL syntax and encoding
103 * rules specified in [RFC 1738]. The name must include both a scheme
104 * (e.g., "http" or "ftp") and a scheme-specific-part. The scheme-
105 * specific-part must include a fully qualified domain name or IP
106 * address as the host.
107 *
108 * When the subjectAltName extension contains a iPAddress, the address
109 * MUST be stored in the octet string in "network byte order," as
110 * specified in RFC 791 [RFC 791]. The least significant bit (LSB) of
111 * each octet is the LSB of the corresponding byte in the network
112 * address. For IP Version 4, as specified in RFC 791, the octet string
113 * MUST contain exactly four octets. For IP Version 6, as specified in
114 * RFC 1883, the octet string MUST contain exactly sixteen octets [RFC
115 * 1883].
116 */
117 public GeneralName(
118 int tag,
119 ASN1Encodable name)
120 {
121 this.obj = name;
122 this.tag = tag;
123 }
124
125 /**
126 * Create a General name for the given tag from the passed in String.
127 *
128 * @param tag tag number
129 * @param name string representation of name
130 */
131 public GeneralName(
132 int tag,
133 String name)
134 {
135 if (tag == rfc822Name || tag == dNSName || tag == uniformResourceIdentifier)
136 {
137 this.tag = tag;
138 this.obj = new DERIA5String(name);
139 }
140 else if (tag == registeredID)
141 {
142 this.tag = tag;
143 this.obj = new DERObjectIdentifier(name);
144 }
145 else
146 {
147 throw new IllegalArgumentException("can't process String for tag: " + tag);
148 }
149 }
150
151 public static GeneralName getInstance(
152 Object obj)
153 {
154 if (obj == null || obj instanceof GeneralName)
155 {
156 return (GeneralName)obj;
157 }
158
159 if (obj instanceof ASN1TaggedObject)
160 {
161 ASN1TaggedObject tagObj = (ASN1TaggedObject)obj;
162 int tag = tagObj.getTagNo();
163
164 switch (tag)
165 {
166 case otherName:
167 return new GeneralName(ASN1Sequence.getInstance(tagObj, false), tag);
168 case rfc822Name:
169 return new GeneralName(DERIA5String.getInstance(tagObj, false), tag);
170 case dNSName:
171 return new GeneralName(DERIA5String.getInstance(tagObj, false), tag);
172 case x400Address:
173 throw new IllegalArgumentException("unknown tag: " + tag);
174 case directoryName:
175 return new GeneralName(ASN1Sequence.getInstance(tagObj, true), tag);
176 case ediPartyName:
177 return new GeneralName(ASN1Sequence.getInstance(tagObj, false), tag);
178 case uniformResourceIdentifier:
179 return new GeneralName(DERIA5String.getInstance(tagObj, false), tag);
180 case iPAddress:
181 return new GeneralName(ASN1OctetString.getInstance(tagObj, false), tag);
182 case registeredID:
183 return new GeneralName(DERObjectIdentifier.getInstance(tagObj, false), tag);
184 }
185 }
186
187 throw new IllegalArgumentException("unknown object in getInstance");
188 }
189
190 public static GeneralName getInstance(
191 ASN1TaggedObject tagObj,
192 boolean explicit)
193 {
194 return GeneralName.getInstance(ASN1TaggedObject.getInstance(tagObj, true));
195 }
196
197 public int getTagNo()
198 {
199 return tag;
200 }
201
202 public DEREncodable getName()
203 {
204 return obj;
205 }
206
207 public DERObject toASN1Object()
208 {
209 if (tag == directoryName) // directoryName is explicitly tagged as it is a CHOICE
210 {
211 return new DERTaggedObject(true, tag, obj);
212 }
213 else
214 {
215 return new DERTaggedObject(false, tag, obj);
216 }
217 }
218 }