Source for gnu.javax.crypto.key.dh.DHKeyPairRawCodec

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