Frames | No Frames |
1: /* PKCS1_V1_5.java -- 2: Copyright (C) 2003, 2006, 2010 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: import gnu.java.security.Registry; 43: import gnu.java.security.sig.rsa.EME_PKCS1_V1_5; 44: import gnu.java.security.util.PRNG; 45: import gnu.java.security.util.Util; 46: 47: import java.util.logging.Level; 48: import java.util.logging.Logger; 49: 50: /** 51: * A padding algorithm implementation of the EME-PKCS1-V1.5 encoding/decoding 52: * algorithm as described in section 7.2 of RFC-3447. This is effectively an 53: * <i>Adapter</i> over an instance of {@link EME_PKCS1_V1_5} initialised with 54: * the RSA public shared modulus length (in bytes). 55: * <p> 56: * References: 57: * <ol> 58: * <li><a href="http://www.ietf.org/rfc/rfc3447.txt">Public-Key Cryptography 59: * Standards (PKCS) #1:</a><br> 60: * RSA Cryptography Specifications Version 2.1.<br> 61: * Jakob Jonsson and Burt Kaliski.</li> 62: * </ol> 63: * 64: * @see EME_PKCS1_V1_5 65: */ 66: public class PKCS1_V1_5 67: extends BasePad 68: { 69: private static final Logger log = Configuration.DEBUG ? 70: Logger.getLogger(PKCS1_V1_5.class.getName()) : null; 71: private EME_PKCS1_V1_5 codec; 72: 73: /** 74: * Trivial package-private constructor for use by the <i>Factory</i> class. 75: * 76: * @see PadFactory 77: */ 78: PKCS1_V1_5() 79: { 80: super(Registry.EME_PKCS1_V1_5_PAD); 81: } 82: 83: public void setup() 84: { 85: codec = EME_PKCS1_V1_5.getInstance(blockSize); 86: } 87: 88: public byte[] pad(final byte[] in, final int offset, final int length) 89: { 90: final byte[] M = new byte[length]; 91: System.arraycopy(in, offset, M, 0, length); 92: final byte[] EM = codec.encode(M); 93: final byte[] result = new byte[blockSize - length]; 94: System.arraycopy(EM, 0, result, 0, result.length); 95: if (Configuration.DEBUG) 96: log.fine("padding: 0x" + Util.toString(result)); 97: return result; 98: } 99: 100: public int unpad(final byte[] in, final int offset, final int length) 101: throws WrongPaddingException 102: { 103: final byte[] EM = new byte[length]; 104: System.arraycopy(in, offset, EM, 0, length); 105: final int result = length - codec.decode(EM).length; 106: if (Configuration.DEBUG) 107: log.fine("padding length: " + String.valueOf(result)); 108: return result; 109: } 110: 111: public boolean selfTest() 112: { 113: final int[] mLen = new int[] { 16, 20, 32, 48, 64 }; 114: final byte[] M = new byte[mLen[mLen.length - 1]]; 115: PRNG.getInstance().nextBytes(M); 116: final byte[] EM = new byte[1024]; 117: byte[] p; 118: int bs, i, j; 119: for (bs = 256; bs < 1025; bs += 256) 120: { 121: init(bs); 122: for (i = 0; i < mLen.length; i++) 123: { 124: j = mLen[i]; 125: p = pad(M, 0, j); 126: if (j + p.length != blockSize) 127: { 128: if (Configuration.DEBUG) 129: log.log(Level.SEVERE, 130: "Length of padded text MUST be a multiple of " 131: + blockSize, new RuntimeException(name())); 132: return false; 133: } 134: System.arraycopy(p, 0, EM, 0, p.length); 135: System.arraycopy(M, 0, EM, p.length, j); 136: try 137: { 138: if (p.length != unpad(EM, 0, blockSize)) 139: { 140: if (Configuration.DEBUG) 141: log.log(Level.SEVERE, "Failed symmetric operation", 142: new RuntimeException(name())); 143: return false; 144: } 145: } 146: catch (WrongPaddingException x) 147: { 148: if (Configuration.DEBUG) 149: log.throwing(this.getClass().getName(), "selfTest", x); 150: return false; 151: } 152: } 153: reset(); 154: } 155: return true; 156: } 157: }