Frames | No Frames |
1: /* Password.java -- opaque wrapper around a password. 2: Copyright (C) 2004, 2006 Free Software Foundation, Inc. 3: 4: This file is a part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2 of the License, or (at 9: your option) any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; if not, write to the Free Software 18: Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 19: USA 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package gnu.javax.security.auth; 40: 41: import gnu.java.security.util.ExpirableObject; 42: 43: import javax.security.auth.DestroyFailedException; 44: 45: /** 46: * Immutible, though destroyable, password class. 47: * 48: * <p>Extends {@link ExpirableObject}, implementing {@link doDestroy()} 49: * in which encapsulated {@link char[]}, and {@link byte[]} password fields 50: * are cleared (elements set to zero) in order to thwart memory heap 51: * snooping. 52: */ 53: public final class Password extends ExpirableObject 54: { 55: 56: // Constants and variables 57: // ------------------------------------------------------------------------- 58: 59: /** 60: * Password stored in {@link char[]} format. 61: */ 62: private final char[] password; 63: 64: /** 65: * Password stored in {@link byte[]} format. 66: */ 67: private final byte[] bPassword; 68: 69: /** 70: * Indicates whether this Password object's {@link doDestroy()} method has 71: * been called. See also, {@link ExpirableObject#Destroy()}. 72: */ 73: private boolean mIsDestroyed = false; 74: 75: // Constructor(s) 76: // ------------------------------------------------------------------------- 77: 78: /** 79: * Create a new expirable Password object that will expire after the 80: * default timeout {@link ExpirableObject#DEFAULT_TIMEOUT}. 81: * 82: * @param password The character array password to associate with this 83: * Password object. 84: */ 85: public Password (char[] password) 86: { 87: this (password, 0, password.length, DEFAULT_TIMEOUT); 88: } 89: 90: /** 91: * Create a new expirable Password object that will expire after the 92: * timeout denoted by constructor parameter, <i>delay</i>. 93: * 94: * @param password The character array password to associate with this 95: * Password object. 96: * @param delay The number of miliseconds before this Password object 97: * will be automatically destroyed. 98: */ 99: public Password (char[] password, long delay) 100: { 101: this (password, 0, password.length, delay); 102: } 103: 104: /** 105: * Create a new expirable Password object that will expire after the 106: * default timeout {@link ExpirableObject#DEFAULT_TIMEOUT}. 107: * 108: * @param password The character array password to associate with this 109: * Password object. 110: * @param offset The <i>password</i> character array parameter element 111: * marking the beginning of the contained password string. 112: * @param length The number of characters, beginning at <i>offset</i>, 113: * to be copied into this object's {@link password} field. 114: */ 115: public Password (char[] password, int offset, int length) 116: { 117: this (password, offset, length, DEFAULT_TIMEOUT); 118: } 119: 120: /** 121: * Create a new expirable Password object that will expire after the 122: * timeout denoted by constructor parameter, <i>delay</i>. 123: * 124: * @param password The character array password to associate with this 125: * Password object. 126: * @param offset The <i>password</i> character array parameter element 127: * marking the beginning of the contained password string. 128: * @param length The number of characters, beginning at <i>offset</i>, 129: * to be copied into this object's {@link password} field. 130: * @param delay The number of miliseconds before this Password object 131: * will be automatically destroyed. 132: */ 133: public Password (char[] password, int offset, int length, long delay) 134: { 135: super (delay); 136: 137: if (offset < 0 || length < 0 || offset + length > password.length) 138: throw new ArrayIndexOutOfBoundsException ("off=" + offset + " length=" + 139: length + " array.length=" + 140: password.length); 141: 142: int i, j; 143: this.password = new char[length]; 144: bPassword = new byte[length]; 145: 146: for(i = 0, j = offset; i < length; i++, j++) 147: { 148: this.password[i] = (char) password[j]; 149: // XXX this should use character encodings, other than ASCII. 150: bPassword[i] = (byte) (password[j] & 0x7F); 151: } 152: } 153: 154: /** 155: * Create a new expirable Password object that will expire after the 156: * default timeout {@link ExpirableObject#DEFAULT_TIMEOUT}. 157: * 158: * @param password The byte array password to associate with this 159: * Password object. 160: */ 161: public Password (byte[] password) 162: { 163: this (password, 0, password.length, DEFAULT_TIMEOUT); 164: } 165: 166: /** 167: * Create a new expirable Password object that will expire after the 168: * timeout denoted by constructor parameter, <i>delay</i>. 169: * 170: * @param password The byte array password to associate with this 171: * Password object. 172: * @param delay The number of miliseconds before this Password object 173: * will be automatically destroyed. 174: */ 175: public Password (byte[] password, long delay) 176: { 177: this (password, 0, password.length, delay); 178: } 179: 180: /** 181: * Create a new expirable Password object that will expire after the 182: * default timeout {@link ExpirableObject#DEFAULT_TIMEOUT}. 183: * 184: * @param password The byte array password to associate with this 185: * Password object. 186: * @param offset The <i>password</i> byte array parameter element 187: * marking the beginning of the contained password string. 188: * @param length The number of bytes, beginning at <i>offset</i>, 189: * to be copied into this object's {@link password} field. 190: */ 191: public Password (byte[] password, int offset, int length) 192: { 193: this (password, offset, length, DEFAULT_TIMEOUT); 194: } 195: 196: /** 197: * Create a new expirable Password object that will expire after the 198: * timeout denoted by constructor parameter, <i>delay</i>. 199: * 200: * @param password The byte array password to associate with this 201: * Password object. 202: * @param offset The <i>password</i> byte array parameter element 203: * marking the beginning of the contained password string. 204: * @param length The number of bytes, beginning at <i>offset</i>, 205: * to be copied into this object's {@link bPassword} field. 206: * @param delay The number of miliseconds before this Password object 207: * will be automatically destroyed. 208: */ 209: public Password (byte[] password, int offset, int length, long delay) 210: { 211: super (delay); 212: 213: if (offset < 0 || length < 0 || offset + length > password.length) 214: throw new ArrayIndexOutOfBoundsException ("off=" + offset + " length=" + 215: length + " array.length=" + 216: password.length); 217: 218: int i, j; 219: this.password = new char[length]; 220: bPassword = new byte[length]; 221: 222: for (i = 0, j = offset; i < length; i++, j++) 223: { 224: this.password[i] = (char) password[j]; 225: bPassword[i] = password[j]; 226: } 227: } 228: 229: // Instance methods 230: // ------------------------------------------------------------------------- 231: 232: /** 233: * Returns a reference to the {@link char[]} password storage field, 234: * {@link password}. 235: */ 236: public synchronized char[] getPassword() 237: { 238: if (mIsDestroyed) 239: throw new IllegalStateException ("Attempted destroyed password access."); 240: 241: return password; 242: } 243: 244: /** 245: * Returns a reference to the {@link byte[]} password storage field, 246: * {@link bPassword}. 247: */ 248: public synchronized byte[] getBytes() 249: { 250: if (mIsDestroyed) 251: throw new IllegalStateException ("Attempted destroyed password access."); 252: 253: return bPassword; 254: } 255: 256: /** 257: * Sets password field char[], and byte[] array elements to zero. 258: * This method implements base class {@link ExpirableObject} abstract 259: * method, {@link ExpirableObject#doDestroy()}. See also, 260: * {@link ExpirableObject#destroy()}. 261: */ 262: protected synchronized void doDestroy() 263: { 264: if (isDestroyed()) 265: return; 266: else 267: { 268: for (int i = 0; i < password.length; i++) 269: password[i] = 0; 270: for (int i = 0; i < bPassword.length; i++) 271: bPassword[i] = 0; 272: mIsDestroyed = true; 273: } 274: } 275: 276: /** 277: * Returns true, or false relative to whether, or not this object's 278: * {@link doDestroy()} method has been called. See also, 279: * {@ExpirableObject#destroy()}. 280: */ 281: public synchronized boolean isDestroyed() 282: { 283: return (mIsDestroyed); 284: } 285: }