Path: blob/master/src/java.base/share/classes/sun/security/x509/GeneralName.java
41159 views
/*1* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.x509;2627import java.io.IOException;2829import sun.security.util.*;3031/**32* This class implements the ASN.1 GeneralName object class.33* <p>34* The ASN.1 syntax for this is:35* <pre>36* GeneralName ::= CHOICE {37* otherName [0] OtherName,38* rfc822Name [1] IA5String,39* dNSName [2] IA5String,40* x400Address [3] ORAddress,41* directoryName [4] Name,42* ediPartyName [5] EDIPartyName,43* uniformResourceIdentifier [6] IA5String,44* iPAddress [7] OCTET STRING,45* registeredID [8] OBJECT IDENTIFIER46* }47* </pre>48* @author Amit Kapoor49* @author Hemma Prafullchandra50*/51public class GeneralName {5253// Private data members54private GeneralNameInterface name = null;5556/**57* Default constructor for the class.58*59* @param name the selected CHOICE from the list.60* @throws NullPointerException if name is null61*/62public GeneralName(GeneralNameInterface name) {63if (name == null) {64throw new NullPointerException("GeneralName must not be null");65}66this.name = name;67}6869/**70* Create the object from its DER encoded value.71*72* @param encName the DER encoded GeneralName.73*/74public GeneralName(DerValue encName) throws IOException {75this(encName, false);76}7778/**79* Create the object from its DER encoded value.80*81* @param encName the DER encoded GeneralName.82* @param nameConstraint true if general name is a name constraint83*/84public GeneralName(DerValue encName, boolean nameConstraint)85throws IOException {86short tag = (byte)(encName.tag & 0x1f);8788// All names except for NAME_DIRECTORY should be encoded with the89// IMPLICIT tag.90switch (tag) {91case GeneralNameInterface.NAME_ANY:92if (encName.isContextSpecific() && encName.isConstructed()) {93encName.resetTag(DerValue.tag_Sequence);94name = new OtherName(encName);95} else {96throw new IOException("Invalid encoding of Other-Name");97}98break;99100case GeneralNameInterface.NAME_RFC822:101if (encName.isContextSpecific() && !encName.isConstructed()) {102encName.resetTag(DerValue.tag_IA5String);103name = new RFC822Name(encName);104} else {105throw new IOException("Invalid encoding of RFC822 name");106}107break;108109case GeneralNameInterface.NAME_DNS:110if (encName.isContextSpecific() && !encName.isConstructed()) {111encName.resetTag(DerValue.tag_IA5String);112name = new DNSName(encName);113} else {114throw new IOException("Invalid encoding of DNSName");115}116break;117118case GeneralNameInterface.NAME_X400:119if (encName.isContextSpecific() && encName.isConstructed()) {120encName.resetTag(DerValue.tag_IA5String);121name = new X400Address(encName);122} else {123throw new IOException("Invalid encoding of X400Address name");124}125break;126127case GeneralNameInterface.NAME_URI:128if (encName.isContextSpecific() && !encName.isConstructed()) {129encName.resetTag(DerValue.tag_IA5String);130name = (nameConstraint ? URIName.nameConstraint(encName) :131new URIName(encName));132} else {133throw new IOException("Invalid encoding of URI");134}135break;136137case GeneralNameInterface.NAME_IP:138if (encName.isContextSpecific() && !encName.isConstructed()) {139encName.resetTag(DerValue.tag_OctetString);140name = new IPAddressName(encName);141} else {142throw new IOException("Invalid encoding of IP address");143}144break;145146case GeneralNameInterface.NAME_OID:147if (encName.isContextSpecific() && !encName.isConstructed()) {148encName.resetTag(DerValue.tag_ObjectId);149name = new OIDName(encName);150} else {151throw new IOException("Invalid encoding of OID name");152}153break;154155case GeneralNameInterface.NAME_DIRECTORY:156if (encName.isContextSpecific() && encName.isConstructed()) {157name = new X500Name(encName.getData());158} else {159throw new IOException("Invalid encoding of Directory name");160}161break;162163case GeneralNameInterface.NAME_EDI:164if (encName.isContextSpecific() && encName.isConstructed()) {165encName.resetTag(DerValue.tag_Sequence);166name = new EDIPartyName(encName);167} else {168throw new IOException("Invalid encoding of EDI name");169}170break;171172default:173throw new IOException("Unrecognized GeneralName tag, ("174+ tag +")");175}176}177178/**179* Return the type of the general name.180*/181public int getType() {182return name.getType();183}184185/**186* Return the GeneralNameInterface name.187*/188public GeneralNameInterface getName() {189//XXXX May want to consider cloning this190return name;191}192193/**194* Return the name as user readable string195*/196public String toString() {197return name.toString();198}199200/**201* Compare this GeneralName with another202*203* @param other GeneralName to compare to this204* @return true if match205*/206public boolean equals(Object other) {207if (this == other) {208return true;209}210if (!(other instanceof GeneralName))211return false;212GeneralNameInterface otherGNI = ((GeneralName)other).name;213try {214return name.constrains(otherGNI) == GeneralNameInterface.NAME_MATCH;215} catch (UnsupportedOperationException ioe) {216return false;217}218}219220/**221* Returns the hash code for this GeneralName.222*223* @return a hash code value.224*/225public int hashCode() {226return name.hashCode();227}228229/**230* Encode the name to the specified DerOutputStream.231*232* @param out the DerOutputStream to encode the GeneralName to.233* @exception IOException on encoding errors.234*/235public void encode(DerOutputStream out) throws IOException {236DerOutputStream tmp = new DerOutputStream();237name.encode(tmp);238int nameType = name.getType();239if (nameType == GeneralNameInterface.NAME_ANY ||240nameType == GeneralNameInterface.NAME_X400 ||241nameType == GeneralNameInterface.NAME_EDI) {242243// implicit, constructed form244out.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,245true, (byte)nameType), tmp);246} else if (nameType == GeneralNameInterface.NAME_DIRECTORY) {247// explicit, constructed form since underlying tag is CHOICE248// (see X.680 section 30.6, part c)249out.write(DerValue.createTag(DerValue.TAG_CONTEXT,250true, (byte)nameType), tmp);251} else {252// implicit, primitive form253out.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,254false, (byte)nameType), tmp);255}256}257}258259260