Source for gnu.javax.net.ssl.provider.CipherSuite

   1: /* CipherSuite.java -- Supported cipher suites.
   2:    Copyright (C) 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.net.ssl.provider;
  40: 
  41: import gnu.java.security.action.GetSecurityPropertyAction;
  42: 
  43: import java.io.IOException;
  44: import java.io.OutputStream;
  45: 
  46: import java.nio.ByteBuffer;
  47: 
  48: import java.security.AccessController;
  49: import java.security.NoSuchAlgorithmException;
  50: import java.security.NoSuchProviderException;
  51: 
  52: import java.util.HashMap;
  53: import java.util.LinkedList;
  54: import java.util.List;
  55: 
  56: import javax.crypto.Cipher;
  57: import javax.crypto.Mac;
  58: import javax.crypto.NoSuchPaddingException;
  59: import javax.crypto.NullCipher;
  60: 
  61: public final class CipherSuite implements Constructed
  62: {
  63: 
  64:   // Constants and fields.
  65:   // -------------------------------------------------------------------------
  66: 
  67:   private static final List<String> tlsSuiteNames = new LinkedList<String>();
  68:   private static final HashMap<String, CipherSuite> namesToSuites = new HashMap<String, CipherSuite>();
  69: 
  70:   // Core TLS cipher suites.
  71:   public static final CipherSuite TLS_NULL_WITH_NULL_NULL =
  72:     new CipherSuite (CipherAlgorithm.NULL,
  73:                      KeyExchangeAlgorithm.NONE,
  74:                      SignatureAlgorithm.ANONYMOUS,
  75:                      MacAlgorithm.NULL, 0, 0x00, 0x00,
  76:                      "TLS_NULL_WITH_NULL_NULL");
  77:   public static final CipherSuite TLS_RSA_WITH_NULL_MD5 =
  78:     new CipherSuite (CipherAlgorithm.NULL,
  79:                      KeyExchangeAlgorithm.RSA,
  80:                      SignatureAlgorithm.RSA,
  81:                      MacAlgorithm.MD5, 0, 0x00, 0x01,
  82:                      "TLS_RSA_WITH_NULL_MD5");
  83:   public static final CipherSuite TLS_RSA_WITH_NULL_SHA =
  84:     new CipherSuite (CipherAlgorithm.NULL,
  85:                      KeyExchangeAlgorithm.RSA,
  86:                      SignatureAlgorithm.RSA,
  87:                      MacAlgorithm.SHA, 0, 0x00, 0x02,
  88:                      "TLS_RSA_WITH_NULL_SHA");
  89:   public static final CipherSuite TLS_RSA_EXPORT_WITH_RC4_40_MD5 =
  90:     new CipherSuite (CipherAlgorithm.RC4,
  91:                      KeyExchangeAlgorithm.RSA,
  92:                      SignatureAlgorithm.RSA,
  93:                      MacAlgorithm.MD5, 5, 0x00, 0x03,
  94:                      "TLS_RSA_EXPORT_WITH_RC4_40_MD5");
  95:   public static final CipherSuite TLS_RSA_WITH_RC4_128_MD5 =
  96:     new CipherSuite (CipherAlgorithm.RC4,
  97:                      KeyExchangeAlgorithm.RSA,
  98:                      SignatureAlgorithm.RSA,
  99:                      MacAlgorithm.MD5, 16, 0x00, 0x04,
 100:                      "TLS_RSA_WITH_RC4_128_MD5");
 101:   public static final CipherSuite TLS_RSA_WITH_RC4_128_SHA =
 102:     new CipherSuite (CipherAlgorithm.RC4,
 103:                      KeyExchangeAlgorithm.RSA,
 104:                      SignatureAlgorithm.RSA,
 105:                      MacAlgorithm.SHA, 16, 0x00, 0x05,
 106:                      "TLS_RSA_WITH_RC4_128_SHA");
 107:   public static final CipherSuite TLS_RSA_EXPORT_WITH_DES40_CBC_SHA =
 108:     new CipherSuite (CipherAlgorithm.DES,
 109:                      KeyExchangeAlgorithm.RSA,
 110:                      SignatureAlgorithm.RSA,
 111:                      MacAlgorithm.SHA, 5, 0x00, 0x08,
 112:                      "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA");
 113:   public static final CipherSuite TLS_RSA_WITH_DES_CBC_SHA =
 114:     new CipherSuite (CipherAlgorithm.DES,
 115:                      KeyExchangeAlgorithm.RSA,
 116:                      SignatureAlgorithm.RSA,
 117:                      MacAlgorithm.SHA, 8, 0x00, 0x09,
 118:                      "TLS_RSA_WITH_DES_CBC_SHA");
 119:   public static final CipherSuite TLS_RSA_WITH_3DES_EDE_CBC_SHA =
 120:     new CipherSuite (CipherAlgorithm.DESede,
 121:                      KeyExchangeAlgorithm.RSA,
 122:                      SignatureAlgorithm.RSA,
 123:                      MacAlgorithm.SHA, 24, 0x00, 0x0A,
 124:                      "TLS_RSA_WITH_3DES_EDE_CBC_SHA");
 125:   public static final CipherSuite TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA =
 126:     new CipherSuite (CipherAlgorithm.DES,
 127:                      KeyExchangeAlgorithm.DH_DSS,
 128:                      SignatureAlgorithm.ANONYMOUS,
 129:                      MacAlgorithm.SHA, 5, 0x00, 0x0B,
 130:                      "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA");
 131:   public static final CipherSuite TLS_DH_DSS_WITH_DES_CBC_SHA =
 132:     new CipherSuite (CipherAlgorithm.DES,
 133:                      KeyExchangeAlgorithm.DH_DSS,
 134:                      SignatureAlgorithm.ANONYMOUS,
 135:                      MacAlgorithm.SHA, 8, 0x00, 0x0C,
 136:                      "TLS_DH_DSS_WITH_DES_CBC_SHA");
 137:   public static final CipherSuite TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA =
 138:     new CipherSuite (CipherAlgorithm.DESede,
 139:                      KeyExchangeAlgorithm.DH_DSS,
 140:                      SignatureAlgorithm.ANONYMOUS,
 141:                      MacAlgorithm.SHA, 24, 0x00, 0x0D,
 142:                      "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA");
 143:   public static final CipherSuite TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA =
 144:     new CipherSuite (CipherAlgorithm.DES,
 145:                      KeyExchangeAlgorithm.DH_RSA,
 146:                      SignatureAlgorithm.ANONYMOUS,
 147:                      MacAlgorithm.SHA, 5, 0x00, 0x0E,
 148:                      "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA");
 149:   public static final CipherSuite TLS_DH_RSA_WITH_DES_CBC_SHA =
 150:     new CipherSuite (CipherAlgorithm.DES,
 151:                      KeyExchangeAlgorithm.DH_RSA,
 152:                      SignatureAlgorithm.ANONYMOUS,
 153:                      MacAlgorithm.SHA, 8, 0x00, 0x0F,
 154:                      "TLS_DH_RSA_WITH_DES_CBC_SHA");
 155:   public static final CipherSuite TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA =
 156:     new CipherSuite (CipherAlgorithm.DESede,
 157:                      KeyExchangeAlgorithm.DH_RSA,
 158:                      SignatureAlgorithm.ANONYMOUS,
 159:                      MacAlgorithm.SHA, 24, 0x00, 0x10,
 160:                      "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA");
 161:   public static final CipherSuite TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA =
 162:     new CipherSuite (CipherAlgorithm.DES,
 163:                      KeyExchangeAlgorithm.DHE_DSS, true,
 164:                      SignatureAlgorithm.DSA,
 165:                      MacAlgorithm.SHA, 5, 0x00, 0x11,
 166:                      "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
 167:   public static final CipherSuite TLS_DHE_DSS_WITH_DES_CBC_SHA =
 168:     new CipherSuite (CipherAlgorithm.DES,
 169:                      KeyExchangeAlgorithm.DHE_DSS, true,
 170:                      SignatureAlgorithm.DSA,
 171:                      MacAlgorithm.SHA, 8, 0x00, 0x12,
 172:                      "TLS_DHE_DSS_WITH_DES_CBC_SHA");
 173:   public static final CipherSuite TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA =
 174:     new CipherSuite (CipherAlgorithm.DESede,
 175:                      KeyExchangeAlgorithm.DHE_DSS, true,
 176:                      SignatureAlgorithm.DSA,
 177:                      MacAlgorithm.SHA, 24, 0x00, 0x13,
 178:                      "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA");
 179:   public static final CipherSuite TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA =
 180:     new CipherSuite (CipherAlgorithm.DES,
 181:                      KeyExchangeAlgorithm.DHE_RSA, true,
 182:                      SignatureAlgorithm.RSA,
 183:                      MacAlgorithm.SHA, 5, 0x00, 0x14,
 184:                      "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA");
 185:   public static final CipherSuite TLS_DHE_RSA_WITH_DES_CBC_SHA =
 186:     new CipherSuite (CipherAlgorithm.DES,
 187:                      KeyExchangeAlgorithm.DHE_RSA, true,
 188:                      SignatureAlgorithm.RSA,
 189:                      MacAlgorithm.SHA, 8, 0x00, 0x15,
 190:                      "TLS_DHE_RSA_WITH_DES_CBC_SHA");
 191:   public static final CipherSuite TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA =
 192:     new CipherSuite (CipherAlgorithm.DESede,
 193:                      KeyExchangeAlgorithm.DHE_RSA, true,
 194:                      SignatureAlgorithm.RSA,
 195:                      MacAlgorithm.SHA, 24, 0x00, 0x16,
 196:                      "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA");
 197: 
 198:   // AES CipherSuites.
 199:   public static final CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA =
 200:     new CipherSuite (CipherAlgorithm.AES,
 201:                      KeyExchangeAlgorithm.RSA,
 202:                      SignatureAlgorithm.RSA,
 203:                      MacAlgorithm.SHA, 16, 0x00, 0x2F,
 204:                      "TLS_RSA_WITH_AES_128_CBC_SHA");
 205:   public static final CipherSuite TLS_DH_DSS_WITH_AES_128_CBC_SHA =
 206:     new CipherSuite (CipherAlgorithm.AES,
 207:                      KeyExchangeAlgorithm.DH_DSS,
 208:                      SignatureAlgorithm.ANONYMOUS,
 209:                      MacAlgorithm.SHA, 16, 0x00, 0x30,
 210:                      "TLS_DH_DSS_WITH_AES_128_CBC_SHA");
 211:   public static final CipherSuite TLS_DH_RSA_WITH_AES_128_CBC_SHA =
 212:     new CipherSuite (CipherAlgorithm.AES,
 213:                      KeyExchangeAlgorithm.DH_RSA,
 214:                      SignatureAlgorithm.ANONYMOUS,
 215:                      MacAlgorithm.SHA, 16, 0x00, 0x31,
 216:                      "TLS_DH_RSA_WITH_AES_128_CBC_SHA");
 217:   public static final CipherSuite TLS_DHE_DSS_WITH_AES_128_CBC_SHA =
 218:     new CipherSuite (CipherAlgorithm.AES,
 219:                      KeyExchangeAlgorithm.DHE_DSS, true,
 220:                      SignatureAlgorithm.DSA,
 221:                      MacAlgorithm.SHA, 16, 0x00, 0x32,
 222:                      "TLS_DHE_DSS_WITH_AES_128_CBC_SHA");
 223:   public static final CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_SHA =
 224:     new CipherSuite (CipherAlgorithm.AES,
 225:                      KeyExchangeAlgorithm.DHE_RSA, true,
 226:                      SignatureAlgorithm.RSA,
 227:                      MacAlgorithm.SHA, 16, 0x00, 0x33,
 228:                      "TLS_DHE_RSA_WITH_AES_128_CBC_SHA");
 229:   public static final CipherSuite TLS_RSA_WITH_AES_256_CBC_SHA =
 230:     new CipherSuite (CipherAlgorithm.AES,
 231:                      KeyExchangeAlgorithm.RSA,
 232:                      SignatureAlgorithm.ANONYMOUS,
 233:                      MacAlgorithm.SHA, 32, 0x00, 0x35,
 234:                      "TLS_RSA_WITH_AES_256_CBC_SHA");
 235:   public static final CipherSuite TLS_DH_DSS_WITH_AES_256_CBC_SHA =
 236:     new CipherSuite (CipherAlgorithm.AES,
 237:                      KeyExchangeAlgorithm.DH_DSS,
 238:                      SignatureAlgorithm.ANONYMOUS,
 239:                      MacAlgorithm.SHA, 32, 0x00, 0x36,
 240:                      "TLS_DH_DSS_WITH_AES_256_CBC_SHA");
 241:   public static final CipherSuite TLS_DH_RSA_WITH_AES_256_CBC_SHA =
 242:     new CipherSuite (CipherAlgorithm.AES,
 243:                      KeyExchangeAlgorithm.DH_RSA,
 244:                      SignatureAlgorithm.ANONYMOUS,
 245:                      MacAlgorithm.SHA, 32, 0x00, 0x37,
 246:                      "TLS_DH_RSA_WITH_AES_256_CBC_SHA");
 247:   public static final CipherSuite TLS_DHE_DSS_WITH_AES_256_CBC_SHA =
 248:     new CipherSuite (CipherAlgorithm.AES,
 249:                      KeyExchangeAlgorithm.DHE_DSS, true,
 250:                      SignatureAlgorithm.DSA,
 251:                      MacAlgorithm.SHA, 32, 0x00, 0x38,
 252:                      "TLS_DHE_DSS_WITH_AES_256_CBC_SHA");
 253:   public static final CipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_SHA =
 254:     new CipherSuite (CipherAlgorithm.AES,
 255:                      KeyExchangeAlgorithm.DHE_RSA, true,
 256:                      SignatureAlgorithm.RSA,
 257:                      MacAlgorithm.SHA, 32, 0x00, 0x39,
 258:                      "TLS_DHE_RSA_WITH_AES_256_CBC_SHA");
 259: 
 260:   // Secure remote password (SRP) ciphersuites
 261:   // Actual ID values are TBD, so these are omitted until they are specified.
 262:   /*public static final CipherSuite TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA =
 263:     new CipherSuite (CipherAlgorithm.DESede,
 264:                      KeyExchangeAlgorithm.SRP,
 265:                      SignatureAlgorithm.ANONYMOUS,
 266:                      MacAlgorithm.SHA, 24, 0x00, 0x50,
 267:                      "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA");
 268:   public static final CipherSuite TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA =
 269:     new CipherSuite (CipherAlgorithm.DESede,
 270:                      KeyExchangeAlgorithm.SRP,
 271:                      SignatureAlgorithm.RSA,
 272:                      MacAlgorithm.SHA, 24, 0x00, 0x51,
 273:                      "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA");
 274:   public static final CipherSuite TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA =
 275:     new CipherSuite (CipherAlgorithm.DESede,
 276:                      KeyExchangeAlgorithm.SRP,
 277:                      SignatureAlgorithm.DSA,
 278:                      MacAlgorithm.SHA, 24, 0x00, 0x52,
 279:                      "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA");
 280:   public static final CipherSuite TLS_SRP_SHA_WITH_AES_128_CBC_SHA =
 281:     new CipherSuite (CipherAlgorithm.AES,
 282:                      KeyExchangeAlgorithm.SRP,
 283:                      SignatureAlgorithm.ANONYMOUS,
 284:                      MacAlgorithm.SHA, 16, 0x00, 0x53,
 285:                      "TLS_SRP_SHA_WITH_AES_128_CBC_SHA");
 286:   public static final CipherSuite TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA =
 287:     new CipherSuite (CipherAlgorithm.AES,
 288:                      KeyExchangeAlgorithm.SRP,
 289:                      SignatureAlgorithm.RSA,
 290:                      MacAlgorithm.SHA, 16, 0x00, 0x54,
 291:                      "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA");
 292:   public static final CipherSuite TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA =
 293:     new CipherSuite (CipherAlgorithm.AES,
 294:                      KeyExchangeAlgorithm.SRP,
 295:                      SignatureAlgorithm.DSA,
 296:                      MacAlgorithm.SHA, 16, 0x00, 0x55,
 297:                      "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA");
 298:   public static final CipherSuite TLS_SRP_SHA_WITH_AES_256_CBC_SHA =
 299:     new CipherSuite (CipherAlgorithm.AES,
 300:                      KeyExchangeAlgorithm.SRP,
 301:                      SignatureAlgorithm.ANONYMOUS,
 302:                      MacAlgorithm.SHA, 32, 0x00, 0x56,
 303:                      "TLS_SRP_SHA_WITH_AES_256_CBC_SHA");
 304:   public static final CipherSuite TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA =
 305:     new CipherSuite (CipherAlgorithm.AES,
 306:                      KeyExchangeAlgorithm.SRP,
 307:                      SignatureAlgorithm.RSA,
 308:                      MacAlgorithm.SHA, 32, 0x00, 0x57,
 309:                      "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA");
 310:   public static final CipherSuite TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA =
 311:     new CipherSuite (CipherAlgorithm.AES,
 312:                      KeyExchangeAlgorithm.SRP,
 313:                      SignatureAlgorithm.DSA,
 314:                      MacAlgorithm.SHA, 32, 0x00, 0x58,
 315:                      "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA");*/
 316: 
 317:   // Pre-shared key suites.
 318:   public static final CipherSuite TLS_PSK_WITH_RC4_128_SHA =
 319:     new CipherSuite(CipherAlgorithm.RC4,
 320:                     KeyExchangeAlgorithm.PSK,
 321:                     SignatureAlgorithm.ANONYMOUS,
 322:                     MacAlgorithm.SHA, 16, 0x00, 0x8A,
 323:                     "TLS_PSK_WITH_RC4_128_SHA");
 324:   public static final CipherSuite TLS_PSK_WITH_3DES_EDE_CBC_SHA =
 325:     new CipherSuite(CipherAlgorithm.DESede,
 326:                     KeyExchangeAlgorithm.PSK,
 327:                     SignatureAlgorithm.ANONYMOUS,
 328:                     MacAlgorithm.SHA, 24, 0x00, 0x8B,
 329:                     "TLS_PSK_WITH_3DES_EDE_CBC_SHA");
 330:   public static final CipherSuite TLS_PSK_WITH_AES_128_CBC_SHA =
 331:     new CipherSuite(CipherAlgorithm.AES,
 332:                     KeyExchangeAlgorithm.PSK,
 333:                     SignatureAlgorithm.ANONYMOUS,
 334:                     MacAlgorithm.SHA, 16, 0x00, 0x8C,
 335:                     "TLS_PSK_WITH_AES_128_CBC_SHA");
 336:   public static final CipherSuite TLS_PSK_WITH_AES_256_CBC_SHA =
 337:     new CipherSuite(CipherAlgorithm.AES,
 338:                     KeyExchangeAlgorithm.PSK,
 339:                     SignatureAlgorithm.ANONYMOUS,
 340:                     MacAlgorithm.SHA, 32, 0x00, 0x8D,
 341:                     "TLS_PSK_WITH_AES_256_CBC_SHA");
 342: 
 343:   public static final CipherSuite TLS_DHE_PSK_WITH_RC4_128_SHA =
 344:     new CipherSuite(CipherAlgorithm.RC4,
 345:                     KeyExchangeAlgorithm.DHE_PSK, true,
 346:                     SignatureAlgorithm.ANONYMOUS,
 347:                     MacAlgorithm.SHA, 16, 0x00, 0x8E,
 348:                     "TLS_DHE_PSK_WITH_RC4_128_SHA");
 349:   public static final CipherSuite TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA =
 350:     new CipherSuite(CipherAlgorithm.DESede,
 351:                     KeyExchangeAlgorithm.DHE_PSK, true,
 352:                     SignatureAlgorithm.ANONYMOUS,
 353:                     MacAlgorithm.SHA, 24, 0x00, 0x8F,
 354:                     "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA");
 355:   public static final CipherSuite TLS_DHE_PSK_WITH_AES_128_CBC_SHA =
 356:     new CipherSuite(CipherAlgorithm.AES,
 357:                     KeyExchangeAlgorithm.DHE_PSK, true,
 358:                     SignatureAlgorithm.ANONYMOUS,
 359:                     MacAlgorithm.SHA, 16, 0x00, 0x90,
 360:                     "TLS_DHE_PSK_WITH_AES_128_CBC_SHA");
 361:   public static final CipherSuite TLS_DHE_PSK_WITH_AES_256_CBC_SHA =
 362:     new CipherSuite(CipherAlgorithm.AES,
 363:                     KeyExchangeAlgorithm.DHE_PSK, true,
 364:                     SignatureAlgorithm.ANONYMOUS,
 365:                     MacAlgorithm.SHA, 32, 0x00, 0x91,
 366:                     "TLS_DHE_PSK_WITH_AES_256_CBC_SHA");
 367: 
 368:   public static final CipherSuite TLS_RSA_PSK_WITH_RC4_128_SHA =
 369:     new CipherSuite(CipherAlgorithm.RC4,
 370:                     KeyExchangeAlgorithm.RSA_PSK,
 371:                     SignatureAlgorithm.ANONYMOUS,
 372:                     MacAlgorithm.SHA, 16, 0x00, 0x92,
 373:                     "TLS_RSA_PSK_WITH_RC4_128_SHA");
 374:   public static final CipherSuite TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA =
 375:     new CipherSuite(CipherAlgorithm.DESede,
 376:                     KeyExchangeAlgorithm.RSA_PSK,
 377:                     SignatureAlgorithm.ANONYMOUS,
 378:                     MacAlgorithm.SHA, 24, 0x00, 0x93,
 379:                     "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA");
 380:   public static final CipherSuite TLS_RSA_PSK_WITH_AES_128_CBC_SHA =
 381:     new CipherSuite(CipherAlgorithm.AES,
 382:                     KeyExchangeAlgorithm.RSA_PSK,
 383:                     SignatureAlgorithm.ANONYMOUS,
 384:                     MacAlgorithm.SHA, 16, 0x00, 0x94,
 385:                     "TLS_RSA_PSK_WITH_AES_128_CBC_SHA");
 386:   public static final CipherSuite TLS_RSA_PSK_WITH_AES_256_CBC_SHA =
 387:     new CipherSuite(CipherAlgorithm.AES,
 388:                     KeyExchangeAlgorithm.RSA_PSK,
 389:                     SignatureAlgorithm.ANONYMOUS,
 390:                     MacAlgorithm.SHA, 32, 0x00, 0x95,
 391:                     "TLS_RSA_PSK_WITH_AES_256_CBC_SHA");
 392: 
 393:   // Ciphersuites from the OpenPGP extension draft.
 394:   // These disappeared from a more recent draft.
 395: /*  public static final CipherSuite TLS_DHE_DSS_WITH_CAST_128_CBC_SHA =
 396:     new CipherSuite (CipherAlgorithm.CAST5,
 397:                      KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
 398:                      SignatureAlgorithm.DSA,
 399:                      MacAlgorithm.SHA, 16, 0x00, 0x70,
 400:                      "TLS_DHE_DSS_WITH_CAST_128_CBC_SHA");
 401:   public static final CipherSuite TLS_DHE_DSS_WITH_CAST_128_CBC_RMD =
 402:     new CipherSuite (CipherAlgorithm.CAST5,
 403:                      KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
 404:                      SignatureAlgorithm.DSA,
 405:                      MacAlgorithm.HMAC_RMD, 16, 0x00, 0x71,
 406:                      "TLS_DHE_DSS_WITH_CAST_128_CBC_RMD");
 407:   public static final CipherSuite TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD =
 408:     new CipherSuite (CipherAlgorithm.DESede,
 409:                      KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
 410:                      SignatureAlgorithm.DSA,
 411:                      MacAlgorithm.HMAC_RMD, 24, 0x00, 0x72,
 412:                      "TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD");
 413:   public static final CipherSuite TLS_DHE_DSS_WITH_AES_128_CBC_RMD =
 414:     new CipherSuite (CipherAlgorithm.AES,
 415:                      KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
 416:                      SignatureAlgorithm.DSA,
 417:                      MacAlgorithm.HMAC_RMD, 16, 0x00, 0x73,
 418:                      "TLS_DHE_DSS_WITH_AES_128_CBC_RMD");
 419:   public static final CipherSuite TLS_DHE_DSS_WITH_AES_256_CBC_RMD =
 420:     new CipherSuite (CipherAlgorithm.AES,
 421:                      KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
 422:                      SignatureAlgorithm.DSA,
 423:                      MacAlgorithm.HMAC_RMD, 32, 0x00, 0x74,
 424:                      "TLS_DHE_DSS_WITH_AES_256_CBC_RMD");
 425:   public static final CipherSuite TLS_DHE_RSA_WITH_CAST_128_CBC_SHA =
 426:     new CipherSuite (CipherAlgorithm.CAST5,
 427:                      KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
 428:                      SignatureAlgorithm.RSA,
 429:                      MacAlgorithm.SHA, 16, 0x00, 0x75,
 430:                      "TLS_DHE_RSA_WITH_CAST_128_CBC_SHA");
 431:   public static final CipherSuite TLS_DHE_RSA_WITH_CAST_128_CBC_RMD =
 432:     new CipherSuite (CipherAlgorithm.CAST5,
 433:                      KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
 434:                      SignatureAlgorithm.RSA,
 435:                      MacAlgorithm.HMAC_RMD, 16, 0x00, 0x76,
 436:                      "TLS_DHE_RSA_WITH_CAST_128_CBC_RMD");
 437:   public static final CipherSuite TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD =
 438:     new CipherSuite (CipherAlgorithm.DESede,
 439:                      KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
 440:                      SignatureAlgorithm.RSA,
 441:                      MacAlgorithm.HMAC_RMD, 24, 0x00, 0x77,
 442:                      "TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD");
 443:   public static final CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_RMD =
 444:     new CipherSuite (CipherAlgorithm.AES,
 445:                      KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
 446:                      SignatureAlgorithm.RSA,
 447:                      MacAlgorithm.HMAC_RMD, 16, 0x00, 0x78,
 448:                      "TLS_DHE_RSA_WITH_AES_128_CBC_RMD");
 449:   public static final CipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_RMD =
 450:     new CipherSuite (CipherAlgorithm.AES,
 451:                      KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
 452:                      SignatureAlgorithm.RSA,
 453:                      MacAlgorithm.HMAC_RMD, 32, 0x00, 0x79,
 454:                      "TLS_DHE_RSA_WITH_AES_256_CBC_RMD");
 455:   public static final CipherSuite TLS_RSA_WITH_CAST_128_CBC_SHA =
 456:     new CipherSuite (CipherAlgorithm.CAST5,
 457:                      KeyExchangeAlgorithm.RSA,
 458:                      SignatureAlgorithm.RSA,
 459:                      MacAlgorithm.SHA, 16, 0x00, 0x7A,
 460:                      "TLS_RSA_WITH_CAST_128_CBC_SHA");
 461:   public static final CipherSuite TLS_RSA_WITH_CAST_128_CBC_RMD =
 462:     new CipherSuite (CipherAlgorithm.CAST5,
 463:                      KeyExchangeAlgorithm.RSA,
 464:                      SignatureAlgorithm.RSA,
 465:                      MacAlgorithm.HMAC_RMD, 16, 0x00, 0x7B,
 466:                      "TLS_RSA_WITH_CAST_128_CBC_RMD");
 467:   public static final CipherSuite TLS_RSA_WITH_3DES_EDE_CBC_RMD =
 468:     new CipherSuite (CipherAlgorithm.DESede,
 469:                      KeyExchangeAlgorithm.RSA,
 470:                      SignatureAlgorithm.RSA,
 471:                      MacAlgorithm.HMAC_RMD, 24, 0x00, 0x7C,
 472:                      "TLS_RSA_WITH_3DES_EDE_CBC_RMD");
 473:   public static final CipherSuite TLS_RSA_WITH_AES_128_CBC_RMD =
 474:     new CipherSuite (CipherAlgorithm.AES,
 475:                      KeyExchangeAlgorithm.RSA,
 476:                      SignatureAlgorithm.RSA,
 477:                      MacAlgorithm.HMAC_RMD, 16, 0x00, 0x7D,
 478:                      "TLS_RSA_WITH_AES_128_CBC_RMD");
 479:   public static final CipherSuite TLS_RSA_WITH_AES_256_CBC_RMD =
 480:     new CipherSuite (CipherAlgorithm.AES,
 481:                      KeyExchangeAlgorithm.RSA,
 482:                      SignatureAlgorithm.RSA,
 483:                      MacAlgorithm.HMAC_RMD, 32, 0x00, 0x7E,
 484:                      "TLS_RSA_WITH_AES_256_CBC_RMD"); */
 485: 
 486:   private final CipherAlgorithm cipherAlgorithm;
 487:   private final KeyExchangeAlgorithm keyExchangeAlgorithm;
 488:   private final SignatureAlgorithm signatureAlgorithm;
 489:   private final MacAlgorithm macAlgorithm;
 490:   private final boolean ephemeralDH;
 491:   private final boolean exportable;
 492:   private final boolean isStream;
 493:   private final int keyLength;
 494:   private final byte[] id;
 495:   private final String name;
 496:   private final boolean isResolved;
 497: 
 498:   // Constructors.
 499:   // -------------------------------------------------------------------------
 500: 
 501:   private CipherSuite (final CipherAlgorithm cipherAlgorithm,
 502:                        final KeyExchangeAlgorithm keyExchangeAlgorithm,
 503:                        final SignatureAlgorithm signatureAlgorithm,
 504:                        final MacAlgorithm macAlgorithm,
 505:                        final int keyLength,
 506:                        final int id1,
 507:                        final int id2,
 508:                        final String name)
 509:   {
 510:     this (cipherAlgorithm, keyExchangeAlgorithm, false, signatureAlgorithm,
 511:           macAlgorithm, keyLength, id1, id2, name);
 512:   }
 513: 
 514:   private CipherSuite (final CipherAlgorithm cipherAlgorithm,
 515:                        final KeyExchangeAlgorithm keyExchangeAlgorithm,
 516:                        final boolean ephemeralDH,
 517:                        final SignatureAlgorithm signatureAlgorithm,
 518:                        final MacAlgorithm macAlgorithm,
 519:                        final int keyLength,
 520:                        final int id1,
 521:                        final int id2,
 522:                        final String name)
 523:   {
 524:     this.cipherAlgorithm = cipherAlgorithm;
 525:     this.keyExchangeAlgorithm = keyExchangeAlgorithm;
 526:     this.ephemeralDH = ephemeralDH;
 527:     this.signatureAlgorithm = signatureAlgorithm;
 528:     this.macAlgorithm = macAlgorithm;
 529:     this.exportable = keyLength <= 5;
 530:     this.isStream = (cipherAlgorithm == CipherAlgorithm.NULL
 531:                      || cipherAlgorithm == CipherAlgorithm.RC4);
 532:     this.keyLength = keyLength;
 533:     this.id = new byte[] { (byte) id1, (byte) id2 };
 534:     this.name = name.intern();
 535:     namesToSuites.put(name, this);
 536:     if (name.startsWith("TLS"))
 537:       {
 538:         tlsSuiteNames.add(name);
 539:       }
 540:     isResolved = true;
 541:   }
 542: 
 543:   private CipherSuite(byte[] id)
 544:   {
 545:     cipherAlgorithm = null;
 546:     keyExchangeAlgorithm = null;
 547:     signatureAlgorithm = null;
 548:     macAlgorithm = null;
 549:     ephemeralDH = false;
 550:     exportable = false;
 551:     isStream = false;
 552:     keyLength = 0;
 553:     this.id = id;
 554:     name = null;
 555:     isResolved = false;
 556:   }
 557: 
 558:   // Class methods.
 559:   // -------------------------------------------------------------------------
 560: 
 561:   /**
 562:    * Returns the cipher suite for the given name, or null if there is no
 563:    * such suite.
 564:    *
 565:    * @return The named cipher suite.
 566:    */
 567:   public static CipherSuite forName(String name)
 568:   {
 569:     if (name.startsWith("SSL_"))
 570:       name = "TLS_" + name.substring(4);
 571:     return namesToSuites.get(name);
 572:   }
 573: 
 574:   public static CipherSuite forValue(final short raw_value)
 575:   {
 576:     byte[] b = new byte[] { (byte) (raw_value >>> 8), (byte) raw_value };
 577:     return new CipherSuite(b).resolve();
 578:   }
 579: 
 580:   public static List<String> availableSuiteNames()
 581:   {
 582:     return tlsSuiteNames;
 583:   }
 584: 
 585:   // Intance methods.
 586:   // -------------------------------------------------------------------------
 587: 
 588:   public CipherAlgorithm cipherAlgorithm ()
 589:   {
 590:     return cipherAlgorithm;
 591:   }
 592: 
 593:   public Cipher cipher () throws NoSuchAlgorithmException, NoSuchPaddingException
 594:   {
 595:     if (cipherAlgorithm == null)
 596:       throw new NoSuchAlgorithmException (toString () + ": unresolved cipher suite");
 597:     if (cipherAlgorithm == CipherAlgorithm.NULL)
 598:       return new NullCipher ();
 599: 
 600:     String alg = null;
 601:     if (cipherAlgorithm == CipherAlgorithm.RC4)
 602:       alg = "RC4";
 603:     else
 604:       alg = cipherAlgorithm + "/CBC/NoPadding";
 605:     GetSecurityPropertyAction gspa =
 606:       new GetSecurityPropertyAction ("jessie.jce.provider");
 607:     final String provider = (String) AccessController.doPrivileged (gspa);
 608:     if (provider != null)
 609:       {
 610:         try
 611:           {
 612:             return Cipher.getInstance (alg, provider);
 613:           }
 614:         catch (NoSuchProviderException nspe)
 615:           {
 616:           }
 617:       }
 618:     return Cipher.getInstance (alg);
 619:   }
 620: 
 621:   public MacAlgorithm macAlgorithm ()
 622:   {
 623:     return macAlgorithm;
 624:   }
 625: 
 626:   public Mac mac(ProtocolVersion version) throws NoSuchAlgorithmException
 627:   {
 628:     if (macAlgorithm == null)
 629:       throw new NoSuchAlgorithmException(toString() + ": unresolved cipher suite");
 630:     if (macAlgorithm == MacAlgorithm.NULL)
 631:       return null;
 632: 
 633:     String macAlg = null;
 634:     if (version == ProtocolVersion.SSL_3)
 635:       {
 636:         macAlg = "SSLv3HMac-" + macAlgorithm;
 637:       }
 638:     else
 639:       {
 640:         if (macAlgorithm == MacAlgorithm.MD5)
 641:           macAlg = "HMac-MD5";
 642:         if (macAlgorithm == MacAlgorithm.SHA)
 643:           macAlg = "HMac-SHA1";
 644:       }
 645: 
 646:     GetSecurityPropertyAction gspa =
 647:       new GetSecurityPropertyAction ("jessie.jce.provider");
 648:     final String provider = AccessController.doPrivileged (gspa);
 649:     if (provider != null)
 650:       {
 651:         try
 652:           {
 653:             return Mac.getInstance(macAlg, provider);
 654:           }
 655:         catch (NoSuchProviderException nspe)
 656:           {
 657:             // Ignore; try any installed provider.
 658:           }
 659:       }
 660:     return Mac.getInstance(macAlg);
 661:   }
 662: 
 663:   public SignatureAlgorithm signatureAlgorithm ()
 664:   {
 665:     return signatureAlgorithm;
 666:   }
 667: 
 668:   public KeyExchangeAlgorithm keyExchangeAlgorithm ()
 669:   {
 670:     return keyExchangeAlgorithm;
 671:   }
 672: 
 673:   public boolean isEphemeralDH ()
 674:   {
 675:     return ephemeralDH;
 676:   }
 677: 
 678:   public int length ()
 679:   {
 680:     return 2;
 681:   }
 682: 
 683:   public void write(OutputStream out) throws IOException
 684:   {
 685:     out.write(id);
 686:   }
 687: 
 688:   public void put (final ByteBuffer buf)
 689:   {
 690:     buf.put (id);
 691:   }
 692: 
 693:   public CipherSuite resolve()
 694:   {
 695:     if (id[0] == 0x00) switch (id[1] & 0xFF)
 696:       {
 697:       case 0x00: return TLS_NULL_WITH_NULL_NULL;
 698:       case 0x01: return TLS_RSA_WITH_NULL_MD5;
 699:       case 0x02: return TLS_RSA_WITH_NULL_SHA;
 700:       case 0x03: return TLS_RSA_EXPORT_WITH_RC4_40_MD5;
 701:       case 0x04: return TLS_RSA_WITH_RC4_128_MD5;
 702:       case 0x05: return TLS_RSA_WITH_RC4_128_SHA;
 703:       case 0x08: return TLS_RSA_EXPORT_WITH_DES40_CBC_SHA;
 704:       case 0x09: return TLS_RSA_WITH_DES_CBC_SHA;
 705:       case 0x0A: return TLS_RSA_WITH_3DES_EDE_CBC_SHA;
 706:       case 0x0B: return TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA;
 707:       case 0x0C: return TLS_DH_DSS_WITH_DES_CBC_SHA;
 708:       case 0x0D: return TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA;
 709:       case 0x0E: return TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA;
 710:       case 0x0F: return TLS_DH_RSA_WITH_DES_CBC_SHA;
 711:       case 0x10: return TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA;
 712:       case 0x11: return TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA;
 713:       case 0x12: return TLS_DHE_DSS_WITH_DES_CBC_SHA;
 714:       case 0x13: return TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA;
 715:       case 0x14: return TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA;
 716:       case 0x15: return TLS_DHE_RSA_WITH_DES_CBC_SHA;
 717:       case 0x16: return TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA;
 718:       case 0x2F: return TLS_RSA_WITH_AES_128_CBC_SHA;
 719:       case 0x30: return TLS_DH_DSS_WITH_AES_128_CBC_SHA;
 720:       case 0x31: return TLS_DH_RSA_WITH_AES_128_CBC_SHA;
 721:       case 0x32: return TLS_DHE_DSS_WITH_AES_128_CBC_SHA;
 722:       case 0x33: return TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
 723:       case 0x35: return TLS_RSA_WITH_AES_256_CBC_SHA;
 724:       case 0x36: return TLS_DH_DSS_WITH_AES_256_CBC_SHA;
 725:       case 0x37: return TLS_DH_RSA_WITH_AES_256_CBC_SHA;
 726:       case 0x38: return TLS_DHE_DSS_WITH_AES_256_CBC_SHA;
 727:       case 0x39: return TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
 728:       /*case 0x50: return TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA;
 729:       case 0x51: return TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA;
 730:       case 0x52: return TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA;
 731:       case 0x53: return TLS_SRP_SHA_WITH_AES_128_CBC_SHA;
 732:       case 0x54: return TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA;
 733:       case 0x55: return TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA;
 734:       case 0x56: return TLS_SRP_SHA_WITH_AES_256_CBC_SHA;
 735:       case 0x57: return TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA;
 736:       case 0x58: return TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA;
 737:       case 0x70: return TLS_DHE_DSS_WITH_CAST_128_CBC_SHA;
 738:       case 0x71: return TLS_DHE_DSS_WITH_CAST_128_CBC_RMD;
 739:       case 0x72: return TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD;
 740:       case 0x73: return TLS_DHE_DSS_WITH_AES_128_CBC_RMD;
 741:       case 0x74: return TLS_DHE_DSS_WITH_AES_256_CBC_RMD;
 742:       case 0x75: return TLS_DHE_RSA_WITH_CAST_128_CBC_SHA;
 743:       case 0x76: return TLS_DHE_RSA_WITH_CAST_128_CBC_RMD;
 744:       case 0x77: return TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD;
 745:       case 0x78: return TLS_DHE_RSA_WITH_AES_128_CBC_RMD;
 746:       case 0x79: return TLS_DHE_RSA_WITH_AES_256_CBC_RMD;
 747:       case 0x7A: return TLS_RSA_WITH_CAST_128_CBC_SHA;
 748:       case 0x7B: return TLS_RSA_WITH_CAST_128_CBC_RMD;
 749:       case 0x7C: return TLS_RSA_WITH_3DES_EDE_CBC_RMD;
 750:       case 0x7D: return TLS_RSA_WITH_AES_128_CBC_RMD;
 751:       case 0x7E: return TLS_RSA_WITH_AES_256_CBC_RMD;*/
 752:       case 0x8A: return TLS_PSK_WITH_RC4_128_SHA;
 753:       case 0x8B: return TLS_PSK_WITH_3DES_EDE_CBC_SHA;
 754:       case 0x8C: return TLS_PSK_WITH_AES_128_CBC_SHA;
 755:       case 0x8D: return TLS_PSK_WITH_AES_256_CBC_SHA;
 756:       case 0x8E: return TLS_DHE_PSK_WITH_RC4_128_SHA;
 757:       case 0x8F: return TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA;
 758:       case 0x90: return TLS_DHE_PSK_WITH_AES_128_CBC_SHA;
 759:       case 0x91: return TLS_DHE_PSK_WITH_AES_256_CBC_SHA;
 760:       case 0x92: return TLS_RSA_PSK_WITH_RC4_128_SHA;
 761:       case 0x93: return TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA;
 762:       case 0x94: return TLS_RSA_PSK_WITH_AES_128_CBC_SHA;
 763:       case 0x95: return TLS_RSA_PSK_WITH_AES_256_CBC_SHA;
 764:       }
 765:     return this;
 766:   }
 767: 
 768:   public boolean isResolved()
 769:   {
 770:     return isResolved;
 771:   }
 772: 
 773:   public int keyLength()
 774:   {
 775:     return keyLength;
 776:   }
 777: 
 778:   public boolean isExportable()
 779:   {
 780:     return exportable;
 781:   }
 782: 
 783:   public boolean isStreamCipher()
 784:   {
 785:     return isStream;
 786:   }
 787: 
 788: //   String getAuthType()
 789: //   {
 790: //     if (keyExchangeAlgorithm == KeyExchangeAlgorithm.RSA)
 791: //       {
 792: //         if (isExportable())
 793: //           {
 794: //             return "RSA_EXPORT";
 795: //           }
 796: //         return "RSA";
 797: //       }
 798: //     return kexName + "_" + sigName;
 799: //   }
 800: 
 801:   public byte[] id()
 802:   {
 803:     return id;
 804:   }
 805: 
 806:   public boolean equals(Object o)
 807:   {
 808:     if (!(o instanceof CipherSuite))
 809:       {
 810:         return false;
 811:       }
 812:     if (o == this)
 813:       return true;
 814:     byte[] id = ((CipherSuite) o).id();
 815:     return (id[0] == this.id[0] &&
 816:             id[1] == this.id[1]);
 817:   }
 818: 
 819:   public int hashCode()
 820:   {
 821:     return 0xFFFF0000 | (id[0] & 0xFF) << 8 | (id[1] & 0xFF);
 822:   }
 823: 
 824:   public String toString (String prefix)
 825:   {
 826:     return toString ();
 827:   }
 828: 
 829:   public String toString()
 830:   {
 831:     if (name == null)
 832:       {
 833:         return "{ " + (id[0] & 0xFF) + ", " + (id[1] & 0xFF) + " }";
 834:       }
 835:     return name;
 836:   }
 837: }