Source for gnu.java.security.key.dss.DSSKeyPairRawCodec

   1: /* DSSKeyPairRawCodec.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.dss;
  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} operations for the
  51:  * <i>Raw</i> format to use with DSS keypairs.
  52:  */
  53: public class DSSKeyPairRawCodec
  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 DSS (Digital Signature Standard)
  65:    * public key according to the <i>Raw</i> format supported by this library.
  66:    * <p>
  67:    * The <i>Raw</i> format for a DSA 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_DSS_PUBLIC_KEY},
  72:    * <li>
  73:    * <li>1-byte version consisting of the constant: 0x01,</li>
  74:    * <li>4-byte count of following bytes representing the DSA parameter
  75:    * <code>p</code> in internet order,</li>
  76:    * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
  77:    * the <code>toByteArray()</code> method on the DSA parameter <code>p</code>,
  78:    * </li>
  79:    * <li>4-byte count of following bytes representing the DSA parameter
  80:    * <code>q</code>,</li>
  81:    * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
  82:    * the <code>toByteArray()</code> method on the DSA parameter <code>q</code>,
  83:    * </li>
  84:    * <li>4-byte count of following bytes representing the DSA parameter
  85:    * <code>g</code>,</li>
  86:    * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
  87:    * the <code>toByteArray()</code> method on the DSA parameter <code>g</code>,
  88:    * </li>
  89:    * <li>4-byte count of following bytes representing the DSA parameter
  90:    * <code>y</code>,</li>
  91:    * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
  92:    * the <code>toByteArray()</code> method on the DSA parameter <code>y</code>,
  93:    * </li>
  94:    * </ol>
  95:    *
  96:    * @param key the key to encode.
  97:    * @return the <i>Raw</i> format encoding of the designated key.
  98:    * @throws IllegalArgumentException if the designated key is not a DSS
  99:    *           (Digital Signature Standard) one.
 100:    * @see Registry#MAGIC_RAW_DSS_PUBLIC_KEY
 101:    */
 102:   public byte[] encodePublicKey(PublicKey key)
 103:   {
 104:     if (! (key instanceof DSSPublicKey))
 105:       throw new IllegalArgumentException("key");
 106: 
 107:     DSSPublicKey dssKey = (DSSPublicKey) key;
 108:     ByteArrayOutputStream baos = new ByteArrayOutputStream();
 109:     // magic
 110:     baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[0]);
 111:     baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[1]);
 112:     baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[2]);
 113:     baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[3]);
 114:     // version
 115:     baos.write(0x01);
 116:     // p
 117:     byte[] buffer = dssKey.getParams().getP().toByteArray();
 118:     int length = buffer.length;
 119:     baos.write(length >>> 24);
 120:     baos.write((length >>> 16) & 0xFF);
 121:     baos.write((length >>> 8) & 0xFF);
 122:     baos.write(length & 0xFF);
 123:     baos.write(buffer, 0, length);
 124:     // q
 125:     buffer = dssKey.getParams().getQ().toByteArray();
 126:     length = buffer.length;
 127:     baos.write(length >>> 24);
 128:     baos.write((length >>> 16) & 0xFF);
 129:     baos.write((length >>> 8) & 0xFF);
 130:     baos.write(length & 0xFF);
 131:     baos.write(buffer, 0, length);
 132:     // g
 133:     buffer = dssKey.getParams().getG().toByteArray();
 134:     length = buffer.length;
 135:     baos.write(length >>> 24);
 136:     baos.write((length >>> 16) & 0xFF);
 137:     baos.write((length >>> 8) & 0xFF);
 138:     baos.write(length & 0xFF);
 139:     baos.write(buffer, 0, length);
 140:     // y
 141:     buffer = dssKey.getY().toByteArray();
 142:     length = buffer.length;
 143:     baos.write(length >>> 24);
 144:     baos.write((length >>> 16) & 0xFF);
 145:     baos.write((length >>> 8) & 0xFF);
 146:     baos.write(length & 0xFF);
 147:     baos.write(buffer, 0, length);
 148:     return baos.toByteArray();
 149:   }
 150: 
 151:   public PublicKey decodePublicKey(byte[] k)
 152:   {
 153:     // magic
 154:     if (k[0] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[0]
 155:         || k[1] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[1]
 156:         || k[2] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[2]
 157:         || k[3] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[3])
 158:       throw new IllegalArgumentException("magic");
 159: 
 160:     // version
 161:     if (k[4] != 0x01)
 162:       throw new IllegalArgumentException("version");
 163: 
 164:     int i = 5;
 165:     int l;
 166:     byte[] buffer;
 167:     // p
 168:     l =  k[i++]         << 24
 169:       | (k[i++] & 0xFF) << 16
 170:       | (k[i++] & 0xFF) << 8
 171:       | (k[i++] & 0xFF);
 172:     buffer = new byte[l];
 173:     System.arraycopy(k, i, buffer, 0, l);
 174:     i += l;
 175:     BigInteger p = new BigInteger(1, buffer);
 176:     // q
 177:     l =  k[i++]         << 24
 178:       | (k[i++] & 0xFF) << 16
 179:       | (k[i++] & 0xFF) << 8
 180:       | (k[i++] & 0xFF);
 181:     buffer = new byte[l];
 182:     System.arraycopy(k, i, buffer, 0, l);
 183:     i += l;
 184:     BigInteger q = new BigInteger(1, buffer);
 185:     // g
 186:     l =  k[i++]         << 24
 187:       | (k[i++] & 0xFF) << 16
 188:       | (k[i++] & 0xFF) << 8
 189:       | (k[i++] & 0xFF);
 190:     buffer = new byte[l];
 191:     System.arraycopy(k, i, buffer, 0, l);
 192:     i += l;
 193:     BigInteger g = new BigInteger(1, buffer);
 194:     // y
 195:     l =  k[i++]         << 24
 196:       | (k[i++] & 0xFF) << 16
 197:       | (k[i++] & 0xFF) << 8
 198:       | (k[i++] & 0xFF);
 199:     buffer = new byte[l];
 200:     System.arraycopy(k, i, buffer, 0, l);
 201:     i += l;
 202:     BigInteger y = new BigInteger(1, buffer);
 203:     return new DSSPublicKey(p, q, g, y);
 204:   }
 205: 
 206:   /**
 207:    * Returns the encoded form of the designated DSS (Digital Signature Standard)
 208:    * private key according to the <i>Raw</i> format supported by this library.
 209:    * <p>
 210:    * The <i>Raw</i> format for a DSA private key, in this implementation, is a
 211:    * byte sequence consisting of the following:
 212:    * <ol>
 213:    * <li>4-byte magic consisting of the value of the literal
 214:    * {@link Registry#MAGIC_RAW_DSS_PRIVATE_KEY},
 215:    * <li>
 216:    * <li>1-byte version consisting of the constant: 0x01,</li>
 217:    * <li>4-byte count of following bytes representing the DSA parameter
 218:    * <code>p</code> in internet order,</li>
 219:    * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
 220:    * the <code>toByteArray()</code> method on the DSA parameter <code>p</code>,
 221:    * </li>
 222:    * <li>4-byte count of following bytes representing the DSA parameter
 223:    * <code>q</code>,</li>
 224:    * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
 225:    * the <code>toByteArray()</code> method on the DSA parameter <code>q</code>,
 226:    * </li>
 227:    * <li>4-byte count of following bytes representing the DSA parameter
 228:    * <code>g</code>,</li>
 229:    * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
 230:    * the <code>toByteArray()</code> method on the DSA parameter <code>g</code>,
 231:    * </li>
 232:    * <li>4-byte count of following bytes representing the DSA parameter
 233:    * <code>x</code>,</li>
 234:    * <li>n-bytes representation of a {@link BigInteger} obtained by invoking
 235:    * the <code>toByteArray()</code> method on the DSA parameter <code>x</code>,
 236:    * </li>
 237:    * </ol>
 238:    *
 239:    * @param key the key to encode.
 240:    * @return the <i>Raw</i> format encoding of the designated key.
 241:    * @throws IllegalArgumentException if the designated key is not a DSS
 242:    *           (Digital Signature Standard) one.
 243:    */
 244:   public byte[] encodePrivateKey(PrivateKey key)
 245:   {
 246:     if (! (key instanceof DSSPrivateKey))
 247:       throw new IllegalArgumentException("key");
 248: 
 249:     DSSPrivateKey dssKey = (DSSPrivateKey) key;
 250:     ByteArrayOutputStream baos = new ByteArrayOutputStream();
 251:     // magic
 252:     baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[0]);
 253:     baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[1]);
 254:     baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[2]);
 255:     baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[3]);
 256:     // version
 257:     baos.write(0x01);
 258:     // p
 259:     byte[] buffer = dssKey.getParams().getP().toByteArray();
 260:     int length = buffer.length;
 261:     baos.write(length >>> 24);
 262:     baos.write((length >>> 16) & 0xFF);
 263:     baos.write((length >>> 8) & 0xFF);
 264:     baos.write(length & 0xFF);
 265:     baos.write(buffer, 0, length);
 266:     // q
 267:     buffer = dssKey.getParams().getQ().toByteArray();
 268:     length = buffer.length;
 269:     baos.write(length >>> 24);
 270:     baos.write((length >>> 16) & 0xFF);
 271:     baos.write((length >>> 8) & 0xFF);
 272:     baos.write(length & 0xFF);
 273:     baos.write(buffer, 0, length);
 274:     // g
 275:     buffer = dssKey.getParams().getG().toByteArray();
 276:     length = buffer.length;
 277:     baos.write(length >>> 24);
 278:     baos.write((length >>> 16) & 0xFF);
 279:     baos.write((length >>> 8) & 0xFF);
 280:     baos.write(length & 0xFF);
 281:     baos.write(buffer, 0, length);
 282:     // x
 283:     buffer = dssKey.getX().toByteArray();
 284:     length = buffer.length;
 285:     baos.write(length >>> 24);
 286:     baos.write((length >>> 16) & 0xFF);
 287:     baos.write((length >>> 8) & 0xFF);
 288:     baos.write(length & 0xFF);
 289:     baos.write(buffer, 0, length);
 290:     return baos.toByteArray();
 291:   }
 292: 
 293:   public PrivateKey decodePrivateKey(byte[] k)
 294:   {
 295:     // magic
 296:     if (k[0] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[0]
 297:         || k[1] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[1]
 298:         || k[2] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[2]
 299:         || k[3] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[3])
 300:       throw new IllegalArgumentException("magic");
 301: 
 302:     // version
 303:     if (k[4] != 0x01)
 304:       throw new IllegalArgumentException("version");
 305: 
 306:     int i = 5;
 307:     int l;
 308:     byte[] buffer;
 309:     // p
 310:     l =  k[i++]         << 24
 311:       | (k[i++] & 0xFF) << 16
 312:       | (k[i++] & 0xFF) << 8
 313:       | (k[i++] & 0xFF);
 314:     buffer = new byte[l];
 315:     System.arraycopy(k, i, buffer, 0, l);
 316:     i += l;
 317:     BigInteger p = new BigInteger(1, buffer);
 318:     // q
 319:     l =  k[i++]         << 24
 320:       | (k[i++] & 0xFF) << 16
 321:       | (k[i++] & 0xFF) << 8
 322:       | (k[i++] & 0xFF);
 323:     buffer = new byte[l];
 324:     System.arraycopy(k, i, buffer, 0, l);
 325:     i += l;
 326:     BigInteger q = new BigInteger(1, buffer);
 327:     // g
 328:     l =  k[i++]         << 24
 329:       | (k[i++] & 0xFF) << 16
 330:       | (k[i++] & 0xFF) << 8
 331:       | (k[i++] & 0xFF);
 332:     buffer = new byte[l];
 333:     System.arraycopy(k, i, buffer, 0, l);
 334:     i += l;
 335:     BigInteger g = new BigInteger(1, buffer);
 336:     // x
 337:     l =  k[i++]         << 24
 338:       | (k[i++] & 0xFF) << 16
 339:       | (k[i++] & 0xFF) << 8
 340:       | (k[i++] & 0xFF);
 341:     buffer = new byte[l];
 342:     System.arraycopy(k, i, buffer, 0, l);
 343:     i += l;
 344:     BigInteger x = new BigInteger(1, buffer);
 345:     return new DSSPrivateKey(p, q, g, x);
 346:   }
 347: }