Frames | No Frames |
1: /* BasePad.java -- 2: Copyright (C) 2001, 2002, 2003, 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.crypto.pad; 40: 41: import gnu.java.security.Configuration; 42: 43: import java.util.Map; 44: import java.util.logging.Level; 45: import java.util.logging.Logger; 46: 47: /** 48: * An abstract class to facilitate implementing padding algorithms. 49: */ 50: public abstract class BasePad 51: implements IPad 52: { 53: private static final Logger log = Logger.getLogger(BasePad.class.getName()); 54: /** The canonical name prefix of the padding algorithm. */ 55: protected String name; 56: /** The block size, in bytes, for this instance. */ 57: protected int blockSize; 58: 59: /** Trivial constructor for use by concrete subclasses. */ 60: protected BasePad(final String name) 61: { 62: super(); 63: 64: this.name = name; 65: blockSize = -1; 66: } 67: 68: public String name() 69: { 70: final StringBuffer sb = new StringBuffer(name); 71: if (blockSize != -1) 72: sb.append('-').append(String.valueOf(8 * blockSize)); 73: return sb.toString(); 74: } 75: 76: public void init(final int bs) throws IllegalStateException 77: { 78: if (blockSize != -1) 79: throw new IllegalStateException(); 80: blockSize = bs; 81: setup(); 82: } 83: 84: /** 85: * Initialises the algorithm with designated attributes. Names, valid and/or 86: * recognisable by all concrete implementations are described in {@link IPad} 87: * class documentation. Other algorithm-specific attributes MUST be documented 88: * in the implementation class of that padding algorithm. 89: * <p> 90: * For compatibility reasons, this method is not declared <i>abstract</i>. 91: * Furthermore, and unless overridden, the default implementation will throw 92: * an {@link UnsupportedOperationException}. Concrete padding algorithms MUST 93: * override this method if they wish to offer an initialisation method that 94: * allows for other than the padding block size parameter to be specified. 95: * 96: * @param attributes a set of name-value pairs that describes the desired 97: * future behaviour of this instance. 98: * @exception IllegalStateException if the instance is already initialised. 99: * @exception IllegalArgumentException if the block size value is invalid. 100: */ 101: public void init(Map attributes) throws IllegalStateException 102: { 103: throw new UnsupportedOperationException(); 104: } 105: 106: public void reset() 107: { 108: blockSize = -1; 109: } 110: 111: /** 112: * A default implementation of a correctness test that exercises the padder 113: * implementation, using block sizes varying from 2 to 256 bytes. 114: * 115: * @return <code>true</code> if the concrete implementation correctly unpads 116: * what it pads for all tested block sizes. Returns <code>false</code> 117: * if the test fails for any block size. 118: */ 119: public boolean selfTest() 120: { 121: final byte[] in = new byte[1024]; 122: for (int bs = 2; bs < 256; bs++) 123: if (! test1BlockSize(bs, in)) 124: return false; 125: return true; 126: } 127: 128: /** 129: * The basic symmetric test for a padder given a specific block size. 130: * <p> 131: * The code ensures that the implementation is capable of unpadding what it 132: * pads. 133: * 134: * @param size the block size to test. 135: * @param buffer a work buffer. It is exposed as an argument for this method 136: * to reduce un-necessary object allocations. 137: * @return <code>true</code> if the test passes; <code>false</code> 138: * otherwise. 139: */ 140: protected boolean test1BlockSize(int size, byte[] buffer) 141: { 142: byte[] padBytes; 143: final int offset = 5; 144: final int limit = buffer.length; 145: this.init(size); 146: for (int i = 0; i < limit - offset - blockSize; i++) 147: { 148: padBytes = pad(buffer, offset, i); 149: if (((i + padBytes.length) % blockSize) != 0) 150: { 151: if (Configuration.DEBUG) 152: log.log(Level.SEVERE, 153: "Length of padded text MUST be a multiple of " 154: + blockSize, new RuntimeException(name())); 155: return false; 156: } 157: System.arraycopy(padBytes, 0, buffer, offset + i, padBytes.length); 158: try 159: { 160: if (padBytes.length != unpad(buffer, offset, i + padBytes.length)) 161: { 162: if (Configuration.DEBUG) 163: log.log(Level.SEVERE, 164: "IPad [" + name() + "] failed symmetric operation", 165: new RuntimeException(name())); 166: return false; 167: } 168: } 169: catch (WrongPaddingException x) 170: { 171: if (Configuration.DEBUG) 172: log.throwing(this.getClass().getName(), "test1BlockSize", x); 173: return false; 174: } 175: } 176: this.reset(); 177: return true; 178: } 179: 180: /** 181: * If any additional checks or resource setup must be done by the subclass, 182: * then this is the hook for it. This method will be called before the 183: * {@link #init(int)} method returns. 184: */ 185: public abstract void setup(); 186: 187: public abstract byte[] pad(byte[] in, int off, int len); 188: 189: public abstract int unpad(byte[] in, int off, int len) 190: throws WrongPaddingException; 191: }