Path: blob/master/src/java.security.jgss/share/classes/sun/security/krb5/internal/HostAddress.java
41161 views
/*1* Copyright (c) 2000, 2020, 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*/136public InetAddress getInetAddress() throws UnknownHostException {137// the type of internet addresses is 2.138if (addrType == Krb5.ADDRTYPE_INET ||139addrType == Krb5.ADDRTYPE_INET6) {140return (InetAddress.getByAddress(address));141} else {142// if it is other type (ISO address, XNS address, etc)143return null;144}145}146147private int getAddrType(InetAddress inetAddress) {148int addressType = 0;149if (inetAddress instanceof Inet4Address)150addressType = Krb5.ADDRTYPE_INET;151else if (inetAddress instanceof Inet6Address)152addressType = Krb5.ADDRTYPE_INET6;153return (addressType);154}155156// implicit default not in Config.java157public HostAddress() throws UnknownHostException {158InetAddress inetAddress = getLocalInetAddress();159addrType = getAddrType(inetAddress);160address = inetAddress.getAddress();161}162163/**164* Creates a HostAddress from the specified address and address type.165*166* Warning: called by nativeccache.c.167*168* @param new_addrType the value of the address type which matches the defined169* address family constants in the Berkeley Standard170* Distributions of Unix.171* @param new_address network address.172* @exception KrbApErrException if address type and address length do not match defined value.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*/229public HostAddress(DerValue encoding) throws Asn1Exception, IOException {230DerValue der = encoding.getData().getDerValue();231if ((der.getTag() & (byte)0x1F) == (byte)0x00) {232addrType = der.getData().getBigInteger().intValue();233}234else235throw new Asn1Exception(Krb5.ASN1_BAD_ID);236der = encoding.getData().getDerValue();237if ((der.getTag() & (byte)0x1F) == (byte)0x01) {238address = der.getData().getOctetString();239}240else241throw new Asn1Exception(Krb5.ASN1_BAD_ID);242if (encoding.getData().available() > 0)243throw new Asn1Exception(Krb5.ASN1_BAD_ID);244}245246/**247* Encodes a HostAddress object.248* @return a byte array of encoded HostAddress object.249* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.250* @exception IOException if an I/O error occurs while reading encoded data.251*/252public byte[] asn1Encode() throws Asn1Exception, IOException {253DerOutputStream bytes = new DerOutputStream();254DerOutputStream temp = new DerOutputStream();255temp.putInteger(this.addrType);256bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);257temp = new DerOutputStream();258temp.putOctetString(address);259bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);260temp = new DerOutputStream();261temp.write(DerValue.tag_Sequence, bytes);262return temp.toByteArray();263}264265/**266* Parses (unmarshal) a host address from a DER input stream. This form267* parsing might be used when expanding a value which is part of268* a constructed sequence and uses explicitly tagged type.269*270* @exception Asn1Exception on error.271* @exception IOException if an I/O error occurs while reading encoded data.272* @param data the Der input stream value, which contains one or more marshaled value.273* @param explicitTag tag number.274* @param optional indicates if this data field is optional275* @return an instance of HostAddress.276*/277public static HostAddress parse(DerInputStream data, byte explicitTag,278boolean optional)279throws Asn1Exception, IOException{280if ((optional) &&281(((byte)data.peekByte() & (byte)0x1F) != explicitTag)) {282return null;283}284DerValue der = data.getDerValue();285if (explicitTag != (der.getTag() & (byte)0x1F)) {286throw new Asn1Exception(Krb5.ASN1_BAD_ID);287}288else {289DerValue subDer = der.getData().getDerValue();290return new HostAddress(subDer);291}292}293294@Override295public String toString() {296StringBuilder sb = new StringBuilder();297sb.append(Arrays.toString(address));298sb.append('(').append(addrType).append(')');299return sb.toString();300}301}302303304