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 }