/** * This method may return false negatives. But if it says two names are equals, then there is some * mechanism that authenticates them as the same principal. */ public boolean equals(GSSName other) throws GSSException { if (this.isAnonymous() || other.isAnonymous()) return false; if (other == this) return true; if (!(other instanceof GSSNameImpl)) return equals(gssManager.createName(other.toString(), other.getStringNameType())); /* * XXX Do a comparison of the appNameStr/appNameBytes if * available. If that fails, then proceed with this test. */ GSSNameImpl that = (GSSNameImpl) other; GSSNameSpi myElement = this.mechElement; GSSNameSpi element = that.mechElement; /* * XXX If they are not of the same mechanism type, convert both to * Kerberos since it is guaranteed to be present. */ if ((myElement == null) && (element != null)) { myElement = this.getElement(element.getMechanism()); } else if ((myElement != null) && (element == null)) { element = that.getElement(myElement.getMechanism()); } if (myElement != null && element != null) { return myElement.equals(element); } if ((this.appNameType != null) && (that.appNameType != null)) { if (!this.appNameType.equals(that.appNameType)) { return false; } byte[] myBytes = null; byte[] bytes = null; try { myBytes = (this.appNameStr != null ? this.appNameStr.getBytes("UTF-8") : this.appNameBytes); bytes = (that.appNameStr != null ? that.appNameStr.getBytes("UTF-8") : that.appNameBytes); } catch (UnsupportedEncodingException e) { // Won't happen } return Arrays.equals(myBytes, bytes); } return false; }
GSSNameImpl(GSSManagerImpl gssManager, GSSNameSpi mechElement) { this.gssManager = gssManager; appNameStr = printableName = mechElement.toString(); appNameType = printableNameType = mechElement.getStringNameType(); this.mechElement = mechElement; elements = new HashMap<Oid, GSSNameSpi>(1); elements.put(mechElement.getMechanism(), this.mechElement); }
/** * Returns a flat name representation for this object. The name format is defined in RFC 2743: * * <pre> * Length Name Description * 2 TOK_ID Token Identifier * For exported name objects, this * must be hex 04 01. * 2 MECH_OID_LEN Length of the Mechanism OID * MECH_OID_LEN MECH_OID Mechanism OID, in DER * 4 NAME_LEN Length of name * NAME_LEN NAME Exported name; format defined in * applicable mechanism draft. * </pre> * * Note that it is not required to canonicalize a name before calling export(). i.e., the name * need not be an MN. If it is not an MN, an implementation defined algorithm can be used for * choosing the mechanism which should export this name. * * @return the flat name representation for this object * @exception GSSException with major codes NAME_NOT_MN, BAD_NAME, BAD_NAME, FAILURE. */ public byte[] export() throws GSSException { if (mechElement == null) { /* Use default mech */ mechElement = getElement(ProviderList.DEFAULT_MECH_OID); } byte[] mechPortion = mechElement.export(); byte[] oidBytes = null; ObjectIdentifier oid = null; try { oid = new ObjectIdentifier(mechElement.getMechanism().toString()); } catch (IOException e) { throw new GSSExceptionImpl(GSSException.FAILURE, "Invalid OID String "); } DerOutputStream dout = new DerOutputStream(); try { dout.putOID(oid); } catch (IOException e) { throw new GSSExceptionImpl(GSSException.FAILURE, "Could not ASN.1 Encode " + oid.toString()); } oidBytes = dout.toByteArray(); byte[] retVal = new byte[2 + 2 + oidBytes.length + 4 + mechPortion.length]; int pos = 0; retVal[pos++] = 0x04; retVal[pos++] = 0x01; retVal[pos++] = (byte) (oidBytes.length >>> 8); retVal[pos++] = (byte) oidBytes.length; System.arraycopy(oidBytes, 0, retVal, pos, oidBytes.length); pos += oidBytes.length; retVal[pos++] = (byte) (mechPortion.length >>> 24); retVal[pos++] = (byte) (mechPortion.length >>> 16); retVal[pos++] = (byte) (mechPortion.length >>> 8); retVal[pos++] = (byte) mechPortion.length; System.arraycopy(mechPortion, 0, retVal, pos, mechPortion.length); return retVal; }