Frames | No Frames |
1: /* RSAKeyPairRawCodec.java -- 2: Copyright 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.java.security.key.rsa; 40: 41: import gnu.java.security.Registry; 42: import gnu.java.security.key.IKeyPairCodec; 43: 44: import java.io.ByteArrayOutputStream; 45: import java.math.BigInteger; 46: import java.security.PrivateKey; 47: import java.security.PublicKey; 48: 49: /** 50: * An object that implements the {@link IKeyPairCodec} interface for the <i>Raw</i> 51: * format to use with RSA keypairs. 52: */ 53: public class RSAKeyPairRawCodec 54: implements IKeyPairCodec 55: { 56: // implicit 0-arguments constructor 57: 58: public int getFormatID() 59: { 60: return RAW_FORMAT; 61: } 62: 63: /** 64: * Returns the encoded form of the designated RSA public key according to the 65: * <i>Raw</i> format supported by this library. 66: * <p> 67: * The <i>Raw</i> format for an RSA public key, in this implementation, is a 68: * byte sequence consisting of the following: 69: * <ol> 70: * <li>4-byte magic consisting of the value of the literal 71: * {@link Registry#MAGIC_RAW_RSA_PUBLIC_KEY},</li> 72: * <li>1-byte version consisting of the constant: 0x01,</li> 73: * <li>4-byte count of following bytes representing the RSA parameter 74: * <code>n</code> (the modulus) in internet order,</li> 75: * <li>n-bytes representation of a {@link BigInteger} obtained by invoking 76: * the <code>toByteArray()</code> method on the RSA parameter <code>n</code>, 77: * </li> 78: * <li>4-byte count of following bytes representing the RSA parameter 79: * <code>e</code> (the public exponent) in internet order,</li> 80: * <li>n-bytes representation of a {@link BigInteger} obtained by invoking 81: * the <code>toByteArray()</code> method on the RSA parameter <code>e</code>. 82: * </li> 83: * </ol> 84: * 85: * @param key the key to encode. 86: * @return the <i>Raw</i> format encoding of the designated key. 87: * @exception IllegalArgumentException if the designated key is not an RSA 88: * one. 89: */ 90: public byte[] encodePublicKey(PublicKey key) 91: { 92: if (! (key instanceof GnuRSAPublicKey)) 93: throw new IllegalArgumentException("key"); 94: 95: GnuRSAPublicKey rsaKey = (GnuRSAPublicKey) key; 96: ByteArrayOutputStream baos = new ByteArrayOutputStream(); 97: // magic 98: baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[0]); 99: baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[1]); 100: baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[2]); 101: baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[3]); 102: // version 103: baos.write(0x01); 104: // n 105: byte[] buffer = rsaKey.getModulus().toByteArray(); 106: int length = buffer.length; 107: baos.write(length >>> 24); 108: baos.write((length >>> 16) & 0xFF); 109: baos.write((length >>> 8) & 0xFF); 110: baos.write(length & 0xFF); 111: baos.write(buffer, 0, length); 112: // e 113: buffer = rsaKey.getPublicExponent().toByteArray(); 114: length = buffer.length; 115: baos.write(length >>> 24); 116: baos.write((length >>> 16) & 0xFF); 117: baos.write((length >>> 8) & 0xFF); 118: baos.write(length & 0xFF); 119: baos.write(buffer, 0, length); 120: return baos.toByteArray(); 121: } 122: 123: public PublicKey decodePublicKey(byte[] k) 124: { 125: // magic 126: if (k[0] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[0] 127: || k[1] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[1] 128: || k[2] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[2] 129: || k[3] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[3]) 130: throw new IllegalArgumentException("magic"); 131: 132: // version 133: if (k[4] != 0x01) 134: throw new IllegalArgumentException("version"); 135: 136: int i = 5; 137: int l; 138: byte[] buffer; 139: // n 140: l = k[i++] << 24 141: | (k[i++] & 0xFF) << 16 142: | (k[i++] & 0xFF) << 8 143: | (k[i++] & 0xFF); 144: buffer = new byte[l]; 145: System.arraycopy(k, i, buffer, 0, l); 146: i += l; 147: BigInteger n = new BigInteger(1, buffer); 148: // e 149: l = k[i++] << 24 150: | (k[i++] & 0xFF) << 16 151: | (k[i++] & 0xFF) << 8 152: | (k[i++] & 0xFF); 153: buffer = new byte[l]; 154: System.arraycopy(k, i, buffer, 0, l); 155: i += l; 156: BigInteger e = new BigInteger(1, buffer); 157: return new GnuRSAPublicKey(n, e); 158: } 159: 160: /** 161: * Returns the encoded form of the designated RSA private key according to the 162: * <i>Raw</i> format supported by this library. 163: * <p> 164: * The <i>Raw</i> format for an RSA private key, in this implementation, is a 165: * byte sequence consisting of the following: 166: * <ol> 167: * <li>4-byte magic consisting of the value of the literal 168: * {@link Registry#MAGIC_RAW_RSA_PRIVATE_KEY},</li> 169: * <li>1-byte version consisting of the constant: 0x01,</li> 170: * <li>4-byte count of following bytes representing the RSA parameter 171: * <code>p</code> (the first prime factor of the modulus) in internet order, 172: * </li> 173: * <li>n-bytes representation of a {@link BigInteger} obtained by invoking 174: * the <code>toByteArray()</code> method on the RSA parameter <code>p</code>, 175: * </li> 176: * <li>4-byte count of following bytes representing the RSA parameter 177: * <code>q</code> (the second prime factor of the modulus) in internet 178: * order,</li> 179: * <li>n-bytes representation of a {@link BigInteger} obtained by invoking 180: * the <code>toByteArray()</code> method on the RSA parameter <code>q</code>, 181: * </li> 182: * <li>4-byte count of following bytes representing the RSA parameter 183: * <code>e</code> (the public exponent) in internet order,</li> 184: * <li>n-bytes representation of a {@link BigInteger} obtained by invoking 185: * the <code>toByteArray()</code> method on the RSA parameter <code>e</code>, 186: * </li> 187: * <li>4-byte count of following bytes representing the RSA parameter 188: * <code>d</code> (the private exponent) in internet order,</li> 189: * <li>n-bytes representation of a {@link BigInteger} obtained by invoking 190: * the <code>toByteArray()</code> method on the RSA parameter <code>d</code>, 191: * </li> 192: * </ol> 193: * 194: * @param key the key to encode. 195: * @return the <i>Raw</i> format encoding of the designated key. 196: */ 197: public byte[] encodePrivateKey(PrivateKey key) 198: { 199: if (! (key instanceof GnuRSAPrivateKey)) 200: throw new IllegalArgumentException("key"); 201: 202: GnuRSAPrivateKey rsaKey = (GnuRSAPrivateKey) key; 203: ByteArrayOutputStream baos = new ByteArrayOutputStream(); 204: // magic 205: baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[0]); 206: baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[1]); 207: baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[2]); 208: baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[3]); 209: // version 210: baos.write(0x01); 211: // p 212: byte[] buffer = rsaKey.getPrimeP().toByteArray(); 213: int length = buffer.length; 214: baos.write(length >>> 24); 215: baos.write((length >>> 16) & 0xFF); 216: baos.write((length >>> 8) & 0xFF); 217: baos.write(length & 0xFF); 218: baos.write(buffer, 0, length); 219: // q 220: buffer = rsaKey.getPrimeQ().toByteArray(); 221: length = buffer.length; 222: baos.write(length >>> 24); 223: baos.write((length >>> 16) & 0xFF); 224: baos.write((length >>> 8) & 0xFF); 225: baos.write(length & 0xFF); 226: baos.write(buffer, 0, length); 227: // e 228: buffer = rsaKey.getPublicExponent().toByteArray(); 229: length = buffer.length; 230: baos.write(length >>> 24); 231: baos.write((length >>> 16) & 0xFF); 232: baos.write((length >>> 8) & 0xFF); 233: baos.write(length & 0xFF); 234: baos.write(buffer, 0, length); 235: // d 236: buffer = rsaKey.getPrivateExponent().toByteArray(); 237: length = buffer.length; 238: baos.write(length >>> 24); 239: baos.write((length >>> 16) & 0xFF); 240: baos.write((length >>> 8) & 0xFF); 241: baos.write(length & 0xFF); 242: baos.write(buffer, 0, length); 243: return baos.toByteArray(); 244: } 245: 246: public PrivateKey decodePrivateKey(byte[] k) 247: { 248: // magic 249: if (k[0] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[0] 250: || k[1] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[1] 251: || k[2] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[2] 252: || k[3] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[3]) 253: throw new IllegalArgumentException("magic"); 254: 255: // version 256: if (k[4] != 0x01) 257: throw new IllegalArgumentException("version"); 258: 259: int i = 5; 260: int l; 261: byte[] buffer; 262: // p 263: l = k[i++] << 24 264: | (k[i++] & 0xFF) << 16 265: | (k[i++] & 0xFF) << 8 266: | (k[i++] & 0xFF); 267: buffer = new byte[l]; 268: System.arraycopy(k, i, buffer, 0, l); 269: i += l; 270: BigInteger p = new BigInteger(1, buffer); 271: // q 272: l = k[i++] << 24 273: | (k[i++] & 0xFF) << 16 274: | (k[i++] & 0xFF) << 8 275: | (k[i++] & 0xFF); 276: buffer = new byte[l]; 277: System.arraycopy(k, i, buffer, 0, l); 278: i += l; 279: BigInteger q = new BigInteger(1, buffer); 280: // e 281: l = k[i++] << 24 282: | (k[i++] & 0xFF) << 16 283: | (k[i++] & 0xFF) << 8 284: | (k[i++] & 0xFF); 285: buffer = new byte[l]; 286: System.arraycopy(k, i, buffer, 0, l); 287: i += l; 288: BigInteger e = new BigInteger(1, buffer); 289: // d 290: l = k[i++] << 24 291: | (k[i++] & 0xFF) << 16 292: | (k[i++] & 0xFF) << 8 293: | (k[i++] & 0xFF); 294: buffer = new byte[l]; 295: System.arraycopy(k, i, buffer, 0, l); 296: i += l; 297: BigInteger d = new BigInteger(1, buffer); 298: return new GnuRSAPrivateKey(p, q, e, d); 299: } 300: }