0N/A/*
2362N/A * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.security.x509;
0N/A
0N/Aimport java.io.IOException;
0N/A
0N/Aimport sun.security.util.*;
0N/A
0N/A/**
0N/A * This class implements the ASN.1 GeneralName object class.
0N/A * <p>
0N/A * The ASN.1 syntax for this is:
0N/A * <pre>
0N/A * GeneralName ::= CHOICE {
0N/A * otherName [0] OtherName,
0N/A * rfc822Name [1] IA5String,
0N/A * dNSName [2] IA5String,
0N/A * x400Address [3] ORAddress,
0N/A * directoryName [4] Name,
0N/A * ediPartyName [5] EDIPartyName,
0N/A * uniformResourceIdentifier [6] IA5String,
0N/A * iPAddress [7] OCTET STRING,
0N/A * registeredID [8] OBJECT IDENTIFIER
0N/A * }
0N/A * </pre>
0N/A * @author Amit Kapoor
0N/A * @author Hemma Prafullchandra
0N/A */
0N/Apublic class GeneralName {
0N/A
0N/A // Private data members
0N/A private GeneralNameInterface name = null;
0N/A
0N/A /**
0N/A * Default constructor for the class.
0N/A *
0N/A * @param name the selected CHOICE from the list.
0N/A * @throws NullPointerException if name is null
0N/A */
0N/A public GeneralName(GeneralNameInterface name) {
0N/A if (name == null) {
0N/A throw new NullPointerException("GeneralName must not be null");
0N/A }
0N/A this.name = name;
0N/A }
0N/A
0N/A /**
0N/A * Create the object from its DER encoded value.
0N/A *
0N/A * @param encName the DER encoded GeneralName.
0N/A */
0N/A public GeneralName(DerValue encName) throws IOException {
0N/A this(encName, false);
0N/A }
0N/A
0N/A /**
0N/A * Create the object from its DER encoded value.
0N/A *
0N/A * @param encName the DER encoded GeneralName.
0N/A * @param nameConstraint true if general name is a name constraint
0N/A */
0N/A public GeneralName(DerValue encName, boolean nameConstraint)
0N/A throws IOException {
0N/A short tag = (byte)(encName.tag & 0x1f);
0N/A
0N/A // All names except for NAME_DIRECTORY should be encoded with the
0N/A // IMPLICIT tag.
0N/A switch (tag) {
0N/A case GeneralNameInterface.NAME_ANY:
0N/A if (encName.isContextSpecific() && encName.isConstructed()) {
0N/A encName.resetTag(DerValue.tag_Sequence);
0N/A name = new OtherName(encName);
0N/A } else {
0N/A throw new IOException("Invalid encoding of Other-Name");
0N/A }
0N/A break;
0N/A
0N/A case GeneralNameInterface.NAME_RFC822:
0N/A if (encName.isContextSpecific() && !encName.isConstructed()) {
0N/A encName.resetTag(DerValue.tag_IA5String);
0N/A name = new RFC822Name(encName);
0N/A } else {
0N/A throw new IOException("Invalid encoding of RFC822 name");
0N/A }
0N/A break;
0N/A
0N/A case GeneralNameInterface.NAME_DNS:
0N/A if (encName.isContextSpecific() && !encName.isConstructed()) {
0N/A encName.resetTag(DerValue.tag_IA5String);
0N/A name = new DNSName(encName);
0N/A } else {
0N/A throw new IOException("Invalid encoding of DNS name");
0N/A }
0N/A break;
0N/A
0N/A case GeneralNameInterface.NAME_URI:
0N/A if (encName.isContextSpecific() && !encName.isConstructed()) {
0N/A encName.resetTag(DerValue.tag_IA5String);
0N/A name = (nameConstraint ? URIName.nameConstraint(encName) :
0N/A new URIName(encName));
0N/A } else {
0N/A throw new IOException("Invalid encoding of URI");
0N/A }
0N/A break;
0N/A
0N/A case GeneralNameInterface.NAME_IP:
0N/A if (encName.isContextSpecific() && !encName.isConstructed()) {
0N/A encName.resetTag(DerValue.tag_OctetString);
0N/A name = new IPAddressName(encName);
0N/A } else {
0N/A throw new IOException("Invalid encoding of IP address");
0N/A }
0N/A break;
0N/A
0N/A case GeneralNameInterface.NAME_OID:
0N/A if (encName.isContextSpecific() && !encName.isConstructed()) {
0N/A encName.resetTag(DerValue.tag_ObjectId);
0N/A name = new OIDName(encName);
0N/A } else {
0N/A throw new IOException("Invalid encoding of OID name");
0N/A }
0N/A break;
0N/A
0N/A case GeneralNameInterface.NAME_DIRECTORY:
0N/A if (encName.isContextSpecific() && encName.isConstructed()) {
0N/A name = new X500Name(encName.getData());
0N/A } else {
0N/A throw new IOException("Invalid encoding of Directory name");
0N/A }
0N/A break;
0N/A
0N/A case GeneralNameInterface.NAME_EDI:
0N/A if (encName.isContextSpecific() && encName.isConstructed()) {
0N/A encName.resetTag(DerValue.tag_Sequence);
0N/A name = new EDIPartyName(encName);
0N/A } else {
0N/A throw new IOException("Invalid encoding of EDI name");
0N/A }
0N/A break;
0N/A
0N/A default:
0N/A throw new IOException("Unrecognized GeneralName tag, ("
0N/A + tag +")");
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Return the type of the general name.
0N/A */
0N/A public int getType() {
0N/A return name.getType();
0N/A }
0N/A
0N/A /**
0N/A * Return the GeneralNameInterface name.
0N/A */
0N/A public GeneralNameInterface getName() {
0N/A //XXXX May want to consider cloning this
0N/A return name;
0N/A }
0N/A
0N/A /**
0N/A * Return the name as user readable string
0N/A */
0N/A public String toString() {
0N/A return name.toString();
0N/A }
0N/A
0N/A /**
0N/A * Compare this GeneralName with another
0N/A *
0N/A * @param other GeneralName to compare to this
0N/A * @returns true if match
0N/A */
0N/A public boolean equals(Object other) {
0N/A if (this == other) {
0N/A return true;
0N/A }
0N/A if (!(other instanceof GeneralName))
0N/A return false;
0N/A GeneralNameInterface otherGNI = ((GeneralName)other).name;
0N/A try {
0N/A return name.constrains(otherGNI) == GeneralNameInterface.NAME_MATCH;
0N/A } catch (UnsupportedOperationException ioe) {
0N/A return false;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns the hash code for this GeneralName.
0N/A *
0N/A * @return a hash code value.
0N/A */
0N/A public int hashCode() {
0N/A return name.hashCode();
0N/A }
0N/A
0N/A /**
0N/A * Encode the name to the specified DerOutputStream.
0N/A *
0N/A * @param out the DerOutputStream to encode the the GeneralName to.
0N/A * @exception IOException on encoding errors.
0N/A */
0N/A public void encode(DerOutputStream out) throws IOException {
0N/A DerOutputStream tmp = new DerOutputStream();
0N/A name.encode(tmp);
0N/A int nameType = name.getType();
0N/A if (nameType == GeneralNameInterface.NAME_ANY ||
0N/A nameType == GeneralNameInterface.NAME_X400 ||
0N/A nameType == GeneralNameInterface.NAME_EDI) {
0N/A
0N/A // implicit, constructed form
0N/A out.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
0N/A true, (byte)nameType), tmp);
0N/A } else if (nameType == GeneralNameInterface.NAME_DIRECTORY) {
0N/A // explicit, constructed form since underlying tag is CHOICE
0N/A // (see X.680 section 30.6, part c)
0N/A out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
0N/A true, (byte)nameType), tmp);
0N/A } else {
0N/A // implicit, primitive form
0N/A out.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
0N/A false, (byte)nameType), tmp);
0N/A }
0N/A }
0N/A}