Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/krb5/internal/HostAddress.java
38923 views
/*1* Copyright (c) 2000, 2006, 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*/2425/*26*27* (C) Copyright IBM Corp. 1999 All Rights Reserved.28* Copyright 1997 The Open Group Research Institute. All rights reserved.29*/3031package sun.security.krb5.internal;3233import sun.security.krb5.Config;34import sun.security.krb5.Asn1Exception;35import sun.security.util.*;36import java.net.InetAddress;37import java.net.Inet4Address;38import java.net.Inet6Address;39import java.net.UnknownHostException;40import java.io.IOException;41import java.util.Arrays;4243/**44* Implements the ASN.1 HostAddress type.45*46* <pre>{@code47* HostAddress ::= SEQUENCE {48* addr-type [0] Int32,49* address [1] OCTET STRING50* }51* }</pre>52*53* <p>54* This definition reflects the Network Working Group RFC 412055* specification available at56* <a href="http://www.ietf.org/rfc/rfc4120.txt">57* http://www.ietf.org/rfc/rfc4120.txt</a>.58*/5960public class HostAddress implements Cloneable {61int addrType;62byte[] address = null;6364private static InetAddress localInetAddress; //caches local inet address65private static final boolean DEBUG = sun.security.krb5.internal.Krb5.DEBUG;66private volatile int hashCode = 0;6768private HostAddress(int dummy) {}6970public Object clone() {71HostAddress new_hostAddress = new HostAddress(0);72new_hostAddress.addrType = addrType;73if (address != null) {74new_hostAddress.address = address.clone();75}76return new_hostAddress;77}787980public int hashCode() {81if (hashCode == 0) {82int result = 17;83result = 37*result + addrType;84if (address != null) {85for (int i=0; i < address.length; i++) {86result = 37*result + address[i];87}88}89hashCode = result;90}91return hashCode;9293}9495public boolean equals(Object obj) {96if (this == obj) {97return true;98}99100if (!(obj instanceof HostAddress)) {101return false;102}103104HostAddress h = (HostAddress)obj;105if (addrType != h.addrType ||106(address != null && h.address == null) ||107(address == null && h.address != null))108return false;109if (address != null && h.address != null) {110if (address.length != h.address.length)111return false;112for (int i = 0; i < address.length; i++)113if (address[i] != h.address[i])114return false;115}116return true;117}118119private static synchronized InetAddress getLocalInetAddress()120throws UnknownHostException {121122if (localInetAddress == null) {123localInetAddress = InetAddress.getLocalHost();124}125if (localInetAddress == null) {126throw new UnknownHostException();127}128return (localInetAddress);129}130131/**132* Gets the InetAddress of this HostAddress.133* @return the IP address for this specified host.134* @exception UnknownHostException if no IP address for the host could be found.135*136*/137public InetAddress getInetAddress() throws UnknownHostException {138// the type of internet addresses is 2.139if (addrType == Krb5.ADDRTYPE_INET ||140addrType == Krb5.ADDRTYPE_INET6) {141return (InetAddress.getByAddress(address));142} else {143// if it is other type (ISO address, XNS address, etc)144return null;145}146}147148private int getAddrType(InetAddress inetAddress) {149int addressType = 0;150if (inetAddress instanceof Inet4Address)151addressType = Krb5.ADDRTYPE_INET;152else if (inetAddress instanceof Inet6Address)153addressType = Krb5.ADDRTYPE_INET6;154return (addressType);155}156157// implicit default not in Config.java158public HostAddress() throws UnknownHostException {159InetAddress inetAddress = getLocalInetAddress();160addrType = getAddrType(inetAddress);161address = inetAddress.getAddress();162}163164/**165* Creates a HostAddress from the specified address and address type.166*167* @param new_addrType the value of the address type which matches the defined168* address family constants in the Berkeley Standard169* Distributions of Unix.170* @param new_address network address.171* @exception KrbApErrException if address type and address length do not match defined value.172*173*/174public HostAddress(int new_addrType, byte[] new_address)175throws KrbApErrException, UnknownHostException {176switch(new_addrType) {177case Krb5.ADDRTYPE_INET: //Internet address178if (new_address.length != 4)179throw new KrbApErrException(0, "Invalid Internet address");180break;181case Krb5.ADDRTYPE_CHAOS:182if (new_address.length != 2) //CHAOSnet address183throw new KrbApErrException(0, "Invalid CHAOSnet address");184break;185case Krb5.ADDRTYPE_ISO: // ISO address186break;187case Krb5.ADDRTYPE_IPX: // XNS address188if (new_address.length != 6)189throw new KrbApErrException(0, "Invalid XNS address");190break;191case Krb5.ADDRTYPE_APPLETALK: //AppleTalk DDP address192if (new_address.length != 3)193throw new KrbApErrException(0, "Invalid DDP address");194break;195case Krb5.ADDRTYPE_DECNET: //DECnet Phase IV address196if (new_address.length != 2)197throw new KrbApErrException(0, "Invalid DECnet Phase IV address");198break;199case Krb5.ADDRTYPE_INET6: //Internet IPv6 address200if (new_address.length != 16)201throw new KrbApErrException(0, "Invalid Internet IPv6 address");202break;203}204205addrType = new_addrType;206if (new_address != null) {207address = new_address.clone();208}209if (DEBUG) {210if (addrType == Krb5.ADDRTYPE_INET ||211addrType == Krb5.ADDRTYPE_INET6) {212System.out.println("Host address is " +213InetAddress.getByAddress(address));214}215}216}217218public HostAddress(InetAddress inetAddress) {219addrType = getAddrType(inetAddress);220address = inetAddress.getAddress();221}222223/**224* Constructs a host address from a single DER-encoded value.225* @param encoding a single DER-encoded value.226* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.227* @exception IOException if an I/O error occurs while reading encoded data.228*229*/230public HostAddress(DerValue encoding) throws Asn1Exception, IOException {231DerValue der = encoding.getData().getDerValue();232if ((der.getTag() & (byte)0x1F) == (byte)0x00) {233addrType = der.getData().getBigInteger().intValue();234}235else236throw new Asn1Exception(Krb5.ASN1_BAD_ID);237der = encoding.getData().getDerValue();238if ((der.getTag() & (byte)0x1F) == (byte)0x01) {239address = der.getData().getOctetString();240}241else242throw new Asn1Exception(Krb5.ASN1_BAD_ID);243if (encoding.getData().available() > 0)244throw new Asn1Exception(Krb5.ASN1_BAD_ID);245}246247/**248* Encodes a HostAddress object.249* @return a byte array of encoded HostAddress object.250* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.251* @exception IOException if an I/O error occurs while reading encoded data.252*253*/254255public byte[] asn1Encode() throws Asn1Exception, IOException {256DerOutputStream bytes = new DerOutputStream();257DerOutputStream temp = new DerOutputStream();258temp.putInteger(this.addrType);259bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);260temp = new DerOutputStream();261temp.putOctetString(address);262bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);263temp = new DerOutputStream();264temp.write(DerValue.tag_Sequence, bytes);265return temp.toByteArray();266}267268/**269* Parses (unmarshal) a host address from a DER input stream. This form270* parsing might be used when expanding a value which is part of271* a constructed sequence and uses explicitly tagged type.272*273* @exception Asn1Exception on error.274* @exception IOException if an I/O error occurs while reading encoded data.275* @param data the Der input stream value, which contains one or more marshaled value.276* @param explicitTag tag number.277* @param optional indicates if this data field is optional278* @return an instance of HostAddress.279*280*/281public static HostAddress parse(DerInputStream data, byte explicitTag,282boolean optional)283throws Asn1Exception, IOException{284if ((optional) &&285(((byte)data.peekByte() & (byte)0x1F) != explicitTag)) {286return null;287}288DerValue der = data.getDerValue();289if (explicitTag != (der.getTag() & (byte)0x1F)) {290throw new Asn1Exception(Krb5.ASN1_BAD_ID);291}292else {293DerValue subDer = der.getData().getDerValue();294return new HostAddress(subDer);295}296}297298@Override299public String toString() {300StringBuilder sb = new StringBuilder();301sb.append(Arrays.toString(address));302sb.append('(').append(addrType).append(')');303return sb.toString();304}305}306307308