KerberosCredMessage.java revision 13532:859397229dc4
1/* 2 * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package javax.security.auth.kerberos; 27 28import javax.security.auth.Destroyable; 29import java.util.Arrays; 30import java.util.Base64; 31import java.util.Objects; 32 33/** 34 * This class encapsulates a Kerberos 5 KRB_CRED message which can be used to 35 * send Kerberos credentials from one principal to another.<p> 36 * 37 * A KRB_CRED message is defined in Section 5.8.1 of the Kerberos Protocol 38 * Specification (<a href=http://www.ietf.org/rfc/rfc4120.txt>RFC 4120</a>) as: 39 * <pre> 40 * KRB-CRED ::= [APPLICATION 22] SEQUENCE { 41 * pvno [0] INTEGER (5), 42 * msg-type [1] INTEGER (22), 43 * tickets [2] SEQUENCE OF Ticket, 44 * enc-part [3] EncryptedData -- EncKrbCredPart 45 * } 46 * </pre> 47 * 48 * @since 9 49 */ 50public final class KerberosCredMessage implements Destroyable { 51 52 final private KerberosPrincipal sender; 53 final private KerberosPrincipal recipient; 54 final private byte[] message; 55 56 private boolean destroyed = false; 57 58 /** 59 * Constructs a {@code KerberosCredMessage} object. 60 * <p> 61 * The contents of the {@code message} argument are copied; subsequent 62 * modification of the byte array does not affect the newly created object. 63 * 64 * @param sender the sender of the message 65 * @param recipient the recipient of the message 66 * @param message the DER encoded KRB_CRED message 67 * @throws NullPointerException if any of sender, recipient 68 * or message is null 69 */ 70 public KerberosCredMessage(KerberosPrincipal sender, 71 KerberosPrincipal recipient, 72 byte[] message) { 73 this.sender = Objects.requireNonNull(sender); 74 this.recipient = Objects.requireNonNull(recipient); 75 this.message = Objects.requireNonNull(message).clone(); 76 } 77 78 /** 79 * Returns the DER encoded form of the KRB_CRED message. 80 * 81 * @return a newly allocated byte array that contains the encoded form 82 * @throws IllegalStateException if the object is destroyed 83 */ 84 public byte[] getEncoded() { 85 if (destroyed) { 86 throw new IllegalStateException("This object is no longer valid"); 87 } 88 return message.clone(); 89 } 90 91 /** 92 * Returns the sender of this message. 93 * 94 * @return the sender 95 * @throws IllegalStateException if the object is destroyed 96 */ 97 public KerberosPrincipal getSender() { 98 if (destroyed) { 99 throw new IllegalStateException("This object is no longer valid"); 100 } 101 return sender; 102 } 103 104 /** 105 * Returns the recipient of this message. 106 * 107 * @return the recipient 108 * @throws IllegalStateException if the object is destroyed 109 */ 110 public KerberosPrincipal getRecipient() { 111 if (destroyed) { 112 throw new IllegalStateException("This object is no longer valid"); 113 } 114 return recipient; 115 } 116 117 /** 118 * Destroys this object by clearing out the message. 119 */ 120 @Override 121 public void destroy() { 122 if (!destroyed) { 123 Arrays.fill(message, (byte)0); 124 destroyed = true; 125 } 126 } 127 128 @Override 129 public boolean isDestroyed() { 130 return destroyed; 131 } 132 133 /** 134 * Returns an informative textual representation of this {@code KerberosCredMessage}. 135 * 136 * @return an informative textual representation of this {@code KerberosCredMessage}. 137 */ 138 @Override 139 public String toString() { 140 if (destroyed) { 141 return "Destroyed KerberosCredMessage"; 142 } else { 143 return "KRB_CRED from " + sender + " to " + recipient + ":\n" 144 + Base64.getUrlEncoder().encodeToString(message); 145 } 146 } 147 148 /** 149 * Returns a hash code for this {@code KerberosCredMessage}. 150 * 151 * @return a hash code for this {@code KerberosCredMessage}. 152 */ 153 @Override 154 public int hashCode() { 155 if (isDestroyed()) { 156 return -1; 157 } else { 158 return Objects.hash(sender, recipient, Arrays.hashCode(message)); 159 } 160 } 161 162 /** 163 * Compares the specified object with this {@code KerberosCredMessage} 164 * for equality. Returns true if the given object is also a 165 * {@code KerberosCredMessage} and the two {@code KerberosCredMessage} 166 * instances are equivalent. More formally two {@code KerberosCredMessage} 167 * instances are equal if they have equal sender, recipient, and encoded 168 * KRB_CRED messages. 169 * A destroyed {@code KerberosCredMessage} object is only equal to itself. 170 * 171 * @param other the object to compare to 172 * @return true if the specified object is equal to this 173 * {@code KerberosCredMessage}, false otherwise. 174 */ 175 @Override 176 public boolean equals(Object other) { 177 if (other == this) { 178 return true; 179 } 180 181 if (! (other instanceof KerberosCredMessage)) { 182 return false; 183 } 184 185 KerberosCredMessage otherMessage = ((KerberosCredMessage) other); 186 if (isDestroyed() || otherMessage.isDestroyed()) { 187 return false; 188 } 189 190 return Objects.equals(sender, otherMessage.sender) 191 && Objects.equals(recipient, otherMessage.recipient) 192 && Arrays.equals(message, otherMessage.message); 193 } 194} 195