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 }