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: */package org.apache.geronimo.crypto.asn1.x509;
017:
018: import org.apache.geronimo.crypto.asn1.ASN1Choice;
019: import org.apache.geronimo.crypto.asn1.ASN1Encodable;
020: import org.apache.geronimo.crypto.asn1.ASN1OctetString;
021: import org.apache.geronimo.crypto.asn1.ASN1Sequence;
022: import org.apache.geronimo.crypto.asn1.ASN1TaggedObject;
023: import org.apache.geronimo.crypto.asn1.DEREncodable;
024: import org.apache.geronimo.crypto.asn1.DERIA5String;
025: import org.apache.geronimo.crypto.asn1.DERObject;
026: import org.apache.geronimo.crypto.asn1.DERObjectIdentifier;
027: import org.apache.geronimo.crypto.asn1.DERTaggedObject;
028:
029: /**
030: * The GeneralName object.
031: * <pre>
032: * GeneralName ::= CHOICE {
033: * otherName [0] OtherName,
034: * rfc822Name [1] IA5String,
035: * dNSName [2] IA5String,
036: * x400Address [3] ORAddress,
037: * directoryName [4] Name,
038: * ediPartyName [5] EDIPartyName,
039: * uniformResourceIdentifier [6] IA5String,
040: * iPAddress [7] OCTET STRING,
041: * registeredID [8] OBJECT IDENTIFIER}
042: *
043: * OtherName ::= SEQUENCE {
044: * type-id OBJECT IDENTIFIER,
045: * value [0] EXPLICIT ANY DEFINED BY type-id }
046: *
047: * EDIPartyName ::= SEQUENCE {
048: * nameAssigner [0] DirectoryString OPTIONAL,
049: * partyName [1] DirectoryString }
050: *
051: * Name ::= CHOICE { RDNSequence }
052: * </pre>
053: */
054: public class GeneralName extends ASN1Encodable implements ASN1Choice {
055: public static final int otherName = 0;
056: public static final int rfc822Name = 1;
057: public static final int dNSName = 2;
058: public static final int x400Address = 3;
059: public static final int directoryName = 4;
060: public static final int ediPartyName = 5;
061: public static final int uniformResourceIdentifier = 6;
062: public static final int iPAddress = 7;
063: public static final int registeredID = 8;
064:
065: DEREncodable obj;
066: int tag;
067:
068: public GeneralName(X509Name dirName) {
069: this .obj = dirName;
070: this .tag = 4;
071: }
072:
073: /**
074: * @deprecated this constructor seems the wrong way round! Use GeneralName(tag, name).
075: */
076: public GeneralName(DERObject name, int tag) {
077: this .obj = name;
078: this .tag = tag;
079: }
080:
081: /**
082: * When the subjectAltName extension contains an Internet mail address,
083: * the address MUST be included as an rfc822Name. The format of an
084: * rfc822Name is an "addr-spec" as defined in RFC 822 [RFC 822].
085: *
086: * When the subjectAltName extension contains a domain name service
087: * label, the domain name MUST be stored in the dNSName (an IA5String).
088: * The name MUST be in the "preferred name syntax," as specified by RFC
089: * 1034 [RFC 1034].
090: *
091: * When the subjectAltName extension contains a URI, the name MUST be
092: * stored in the uniformResourceIdentifier (an IA5String). The name MUST
093: * be a non-relative URL, and MUST follow the URL syntax and encoding
094: * rules specified in [RFC 1738]. The name must include both a scheme
095: * (e.g., "http" or "ftp") and a scheme-specific-part. The scheme-
096: * specific-part must include a fully qualified domain name or IP
097: * address as the host.
098: *
099: * When the subjectAltName extension contains a iPAddress, the address
100: * MUST be stored in the octet string in "network byte order," as
101: * specified in RFC 791 [RFC 791]. The least significant bit (LSB) of
102: * each octet is the LSB of the corresponding byte in the network
103: * address. For IP Version 4, as specified in RFC 791, the octet string
104: * MUST contain exactly four octets. For IP Version 6, as specified in
105: * RFC 1883, the octet string MUST contain exactly sixteen octets [RFC
106: * 1883].
107: */
108: public GeneralName(int tag, ASN1Encodable name) {
109: this .obj = name;
110: this .tag = tag;
111: }
112:
113: /**
114: * Create a General name for the given tag from the passed in String.
115: *
116: * @param tag tag number
117: * @param name string representation of name
118: */
119: public GeneralName(int tag, String name) {
120: if (tag == rfc822Name || tag == dNSName
121: || tag == uniformResourceIdentifier) {
122: this .tag = tag;
123: this .obj = new DERIA5String(name);
124: } else if (tag == registeredID) {
125: this .tag = tag;
126: this .obj = new DERObjectIdentifier(name);
127: } else {
128: throw new IllegalArgumentException(
129: "can't process String for tag: " + tag);
130: }
131: }
132:
133: public static GeneralName getInstance(Object obj) {
134: if (obj == null || obj instanceof GeneralName) {
135: return (GeneralName) obj;
136: }
137:
138: if (obj instanceof ASN1TaggedObject) {
139: ASN1TaggedObject tagObj = (ASN1TaggedObject) obj;
140: int tag = tagObj.getTagNo();
141:
142: switch (tag) {
143: case otherName:
144: return new GeneralName(ASN1Sequence.getInstance(tagObj,
145: false), tag);
146: case rfc822Name:
147: return new GeneralName(DERIA5String.getInstance(tagObj,
148: false), tag);
149: case dNSName:
150: return new GeneralName(DERIA5String.getInstance(tagObj,
151: false), tag);
152: case x400Address:
153: throw new IllegalArgumentException("unknown tag: "
154: + tag);
155: case directoryName:
156: return new GeneralName(ASN1Sequence.getInstance(tagObj,
157: true), tag);
158: case ediPartyName:
159: return new GeneralName(ASN1Sequence.getInstance(tagObj,
160: false), tag);
161: case uniformResourceIdentifier:
162: return new GeneralName(DERIA5String.getInstance(tagObj,
163: false), tag);
164: case iPAddress:
165: return new GeneralName(ASN1OctetString.getInstance(
166: tagObj, false), tag);
167: case registeredID:
168: return new GeneralName(DERObjectIdentifier.getInstance(
169: tagObj, false), tag);
170: }
171: }
172:
173: throw new IllegalArgumentException(
174: "unknown object in getInstance");
175: }
176:
177: public static GeneralName getInstance(ASN1TaggedObject tagObj,
178: boolean explicit) {
179: return GeneralName.getInstance(ASN1TaggedObject.getInstance(
180: tagObj, true));
181: }
182:
183: public int getTagNo() {
184: return tag;
185: }
186:
187: public DEREncodable getName() {
188: return obj;
189: }
190:
191: public DERObject toASN1Object() {
192: if (tag == directoryName) // directoryName is explicitly tagged as it is a CHOICE
193: {
194: return new DERTaggedObject(true, tag, obj);
195: } else {
196: return new DERTaggedObject(false, tag, obj);
197: }
198: }
199: }
|