Source for gnu.javax.crypto.key.srp6.SRPKeyPairRawCodec

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