Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java
38918 views
/*1* Copyright (c) 2000, 2013, 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*/2425package javax.security.auth.kerberos;2627import java.io.*;28import java.util.Arrays;29import javax.crypto.SecretKey;30import javax.security.auth.Destroyable;31import javax.security.auth.DestroyFailedException;32import sun.misc.HexDumpEncoder;33import sun.security.krb5.Asn1Exception;34import sun.security.krb5.PrincipalName;35import sun.security.krb5.EncryptionKey;36import sun.security.krb5.EncryptedData;37import sun.security.krb5.KrbException;38import sun.security.krb5.KrbCryptoException;39import sun.security.util.DerValue;4041/**42* This class encapsulates a Kerberos encryption key. It is not associated43* with a principal and may represent an ephemeral session key.44*45* @author Mayank Upadhyay46* @since 1.447*48* @serial include49*/50class KeyImpl implements SecretKey, Destroyable, Serializable {5152private static final long serialVersionUID = -7889313790214321193L;5354private transient byte[] keyBytes;55private transient int keyType;56private transient volatile boolean destroyed = false;575859/**60* Constructs a KeyImpl from the given bytes.61*62* @param keyBytes the raw bytes for the secret key63* @param keyType the key type for the secret key as defined by the64* Kerberos protocol specification.65*/66public KeyImpl(byte[] keyBytes,67int keyType) {68this.keyBytes = keyBytes.clone();69this.keyType = keyType;70}7172/**73* Constructs a KeyImpl from a password.74*75* @param principal the principal from which to derive the salt76* @param password the password that should be used to compute the77* key.78* @param algorithm the name for the algorithm that this key wil be79* used for. This parameter may be null in which case "DES" will be80* assumed.81*/82public KeyImpl(KerberosPrincipal principal,83char[] password,84String algorithm) {8586try {87PrincipalName princ = new PrincipalName(principal.getName());88EncryptionKey key =89new EncryptionKey(password, princ.getSalt(), algorithm);90this.keyBytes = key.getBytes();91this.keyType = key.getEType();92} catch (KrbException e) {93throw new IllegalArgumentException(e.getMessage());94}95}9697/**98* Returns the keyType for this key as defined in the Kerberos Spec.99*/100public final int getKeyType() {101if (destroyed)102throw new IllegalStateException("This key is no longer valid");103return keyType;104}105106/*107* Methods from java.security.Key108*/109110public final String getAlgorithm() {111return getAlgorithmName(keyType);112}113114private String getAlgorithmName(int eType) {115if (destroyed)116throw new IllegalStateException("This key is no longer valid");117118switch (eType) {119case EncryptedData.ETYPE_DES_CBC_CRC:120case EncryptedData.ETYPE_DES_CBC_MD5:121return "DES";122123case EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD:124return "DESede";125126case EncryptedData.ETYPE_ARCFOUR_HMAC:127return "ArcFourHmac";128129case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96:130return "AES128";131132case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96:133return "AES256";134135case EncryptedData.ETYPE_NULL:136return "NULL";137138default:139throw new IllegalArgumentException(140"Unsupported encryption type: " + eType);141}142}143144public final String getFormat() {145if (destroyed)146throw new IllegalStateException("This key is no longer valid");147return "RAW";148}149150public final byte[] getEncoded() {151if (destroyed)152throw new IllegalStateException("This key is no longer valid");153return keyBytes.clone();154}155156public void destroy() throws DestroyFailedException {157if (!destroyed) {158destroyed = true;159Arrays.fill(keyBytes, (byte) 0);160}161}162163public boolean isDestroyed() {164return destroyed;165}166167/**168* @serialData this {@code KeyImpl} is serialized by169* writing out the ASN1 Encoded bytes of the encryption key.170* The ASN1 encoding is defined in RFC4120 and as follows:171* EncryptionKey ::= SEQUENCE {172* keytype [0] Int32 -- actually encryption type --,173* keyvalue [1] OCTET STRING174* }175*/176private void writeObject(ObjectOutputStream ois)177throws IOException {178if (destroyed) {179throw new IOException("This key is no longer valid");180}181182try {183ois.writeObject((new EncryptionKey(keyType, keyBytes)).asn1Encode());184} catch (Asn1Exception ae) {185throw new IOException(ae.getMessage());186}187}188189private void readObject(ObjectInputStream ois)190throws IOException, ClassNotFoundException {191try {192EncryptionKey encKey = new EncryptionKey(new193DerValue((byte[])ois.readObject()));194keyType = encKey.getEType();195keyBytes = encKey.getBytes();196} catch (Asn1Exception ae) {197throw new IOException(ae.getMessage());198}199}200201public String toString() {202HexDumpEncoder hd = new HexDumpEncoder();203return "EncryptionKey: keyType=" + keyType204+ " keyBytes (hex dump)="205+ (keyBytes == null || keyBytes.length == 0 ?206" Empty Key" :207'\n' + hd.encodeBuffer(keyBytes)208+ '\n');209210211}212213public int hashCode() {214int result = 17;215if(isDestroyed()) {216return result;217}218result = 37 * result + Arrays.hashCode(keyBytes);219return 37 * result + keyType;220}221222public boolean equals(Object other) {223224if (other == this)225return true;226227if (! (other instanceof KeyImpl)) {228return false;229}230231KeyImpl otherKey = ((KeyImpl) other);232if (isDestroyed() || otherKey.isDestroyed()) {233return false;234}235236if(keyType != otherKey.getKeyType() ||237!Arrays.equals(keyBytes, otherKey.getEncoded())) {238return false;239}240241return true;242}243}244245246