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