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", false);
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", false);
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", false);
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", false);
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", false);
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", false);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", true);
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", false);
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", true);
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", true);
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", true);
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", false);
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", true);
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", true);
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", true);
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 boolean isCBCMode;
494   private final int keyLength;
495   private final byte[] id;
496   private final String name;
497   private final boolean isResolved;
498 
499   // Constructors.
500   // -------------------------------------------------------------------------
501 
CipherSuite(final CipherAlgorithm cipherAlgorithm, final KeyExchangeAlgorithm keyExchangeAlgorithm, final SignatureAlgorithm signatureAlgorithm, final MacAlgorithm macAlgorithm, final int keyLength, final int id1, final int id2, final String name, final boolean isCBCMode)502   private CipherSuite (final CipherAlgorithm cipherAlgorithm,
503                        final KeyExchangeAlgorithm keyExchangeAlgorithm,
504                        final SignatureAlgorithm signatureAlgorithm,
505                        final MacAlgorithm macAlgorithm,
506                        final int keyLength,
507                        final int id1,
508                        final int id2,
509                        final String name,
510                        final boolean isCBCMode)
511   {
512     this (cipherAlgorithm, keyExchangeAlgorithm, false, signatureAlgorithm,
513           macAlgorithm, keyLength, id1, id2, name, isCBCMode);
514   }
515 
CipherSuite(final CipherAlgorithm cipherAlgorithm, final KeyExchangeAlgorithm keyExchangeAlgorithm, final boolean ephemeralDH, final SignatureAlgorithm signatureAlgorithm, final MacAlgorithm macAlgorithm, final int keyLength, final int id1, final int id2, final String name, final boolean isCBCMode)516   private CipherSuite (final CipherAlgorithm cipherAlgorithm,
517                        final KeyExchangeAlgorithm keyExchangeAlgorithm,
518                        final boolean ephemeralDH,
519                        final SignatureAlgorithm signatureAlgorithm,
520                        final MacAlgorithm macAlgorithm,
521                        final int keyLength,
522                        final int id1,
523                        final int id2,
524                        final String name,
525                        final boolean isCBCMode)
526   {
527     this.cipherAlgorithm = cipherAlgorithm;
528     this.keyExchangeAlgorithm = keyExchangeAlgorithm;
529     this.ephemeralDH = ephemeralDH;
530     this.signatureAlgorithm = signatureAlgorithm;
531     this.macAlgorithm = macAlgorithm;
532     this.exportable = keyLength <= 5;
533     this.isStream = (cipherAlgorithm == CipherAlgorithm.NULL
534                      || cipherAlgorithm == CipherAlgorithm.RC4);
535     this.isCBCMode = isCBCMode;
536     this.keyLength = keyLength;
537     this.id = new byte[] { (byte) id1, (byte) id2 };
538     this.name = name.intern();
539     namesToSuites.put(name, this);
540     if (name.startsWith("TLS"))
541       {
542         tlsSuiteNames.add(name);
543       }
544     isResolved = true;
545   }
546 
CipherSuite(byte[] id)547   private CipherSuite(byte[] id)
548   {
549     cipherAlgorithm = null;
550     keyExchangeAlgorithm = null;
551     signatureAlgorithm = null;
552     macAlgorithm = null;
553     ephemeralDH = false;
554     exportable = false;
555     isStream = false;
556     isCBCMode = false;
557     keyLength = 0;
558     this.id = id;
559     name = null;
560     isResolved = false;
561   }
562 
563   // Class methods.
564   // -------------------------------------------------------------------------
565 
566   /**
567    * Returns the cipher suite for the given name, or null if there is no
568    * such suite.
569    *
570    * @return The named cipher suite.
571    */
forName(String name)572   public static CipherSuite forName(String name)
573   {
574     if (name.startsWith("SSL_"))
575       name = "TLS_" + name.substring(4);
576     return namesToSuites.get(name);
577   }
578 
forValue(final short raw_value)579   public static CipherSuite forValue(final short raw_value)
580   {
581     byte[] b = new byte[] { (byte) (raw_value >>> 8), (byte) raw_value };
582     return new CipherSuite(b).resolve();
583   }
584 
availableSuiteNames()585   public static List<String> availableSuiteNames()
586   {
587     return tlsSuiteNames;
588   }
589 
590   // Intance methods.
591   // -------------------------------------------------------------------------
592 
cipherAlgorithm()593   public CipherAlgorithm cipherAlgorithm ()
594   {
595     return cipherAlgorithm;
596   }
597 
cipher()598   public Cipher cipher () throws NoSuchAlgorithmException, NoSuchPaddingException
599   {
600     if (cipherAlgorithm == null)
601       throw new NoSuchAlgorithmException (toString () + ": unresolved cipher suite");
602     if (cipherAlgorithm == CipherAlgorithm.NULL)
603       return new NullCipher ();
604 
605     String alg = null;
606     if (isCBCMode)
607       alg = cipherAlgorithm + "/CBC/NoPadding";
608     else
609       alg = cipherAlgorithm.toString();
610     GetSecurityPropertyAction gspa =
611       new GetSecurityPropertyAction ("jessie.jce.provider");
612     final String provider = (String) AccessController.doPrivileged (gspa);
613     if (provider != null)
614       {
615         try
616           {
617             return Cipher.getInstance (alg, provider);
618           }
619         catch (NoSuchProviderException nspe)
620           {
621           }
622       }
623     return Cipher.getInstance (alg);
624   }
625 
macAlgorithm()626   public MacAlgorithm macAlgorithm ()
627   {
628     return macAlgorithm;
629   }
630 
mac(ProtocolVersion version)631   public Mac mac(ProtocolVersion version) throws NoSuchAlgorithmException
632   {
633     if (macAlgorithm == null)
634       throw new NoSuchAlgorithmException(toString() + ": unresolved cipher suite");
635     if (macAlgorithm == MacAlgorithm.NULL)
636       return null;
637 
638     String macAlg = null;
639     if (version == ProtocolVersion.SSL_3)
640       {
641         macAlg = "SSLv3HMac-" + macAlgorithm;
642       }
643     else
644       {
645         if (macAlgorithm == MacAlgorithm.MD5)
646           macAlg = "HMac-MD5";
647         if (macAlgorithm == MacAlgorithm.SHA)
648           macAlg = "HMac-SHA1";
649       }
650 
651     GetSecurityPropertyAction gspa =
652       new GetSecurityPropertyAction ("jessie.jce.provider");
653     final String provider = AccessController.doPrivileged (gspa);
654     if (provider != null)
655       {
656         try
657           {
658             return Mac.getInstance(macAlg, provider);
659           }
660         catch (NoSuchProviderException nspe)
661           {
662             // Ignore; try any installed provider.
663           }
664       }
665     return Mac.getInstance(macAlg);
666   }
667 
signatureAlgorithm()668   public SignatureAlgorithm signatureAlgorithm ()
669   {
670     return signatureAlgorithm;
671   }
672 
keyExchangeAlgorithm()673   public KeyExchangeAlgorithm keyExchangeAlgorithm ()
674   {
675     return keyExchangeAlgorithm;
676   }
677 
isEphemeralDH()678   public boolean isEphemeralDH ()
679   {
680     return ephemeralDH;
681   }
682 
length()683   public int length ()
684   {
685     return 2;
686   }
687 
write(OutputStream out)688   public void write(OutputStream out) throws IOException
689   {
690     out.write(id);
691   }
692 
put(final ByteBuffer buf)693   public void put (final ByteBuffer buf)
694   {
695     buf.put (id);
696   }
697 
resolve()698   public CipherSuite resolve()
699   {
700     if (id[0] == 0x00) switch (id[1] & 0xFF)
701       {
702       case 0x00: return TLS_NULL_WITH_NULL_NULL;
703       case 0x01: return TLS_RSA_WITH_NULL_MD5;
704       case 0x02: return TLS_RSA_WITH_NULL_SHA;
705       case 0x03: return TLS_RSA_EXPORT_WITH_RC4_40_MD5;
706       case 0x04: return TLS_RSA_WITH_RC4_128_MD5;
707       case 0x05: return TLS_RSA_WITH_RC4_128_SHA;
708       case 0x08: return TLS_RSA_EXPORT_WITH_DES40_CBC_SHA;
709       case 0x09: return TLS_RSA_WITH_DES_CBC_SHA;
710       case 0x0A: return TLS_RSA_WITH_3DES_EDE_CBC_SHA;
711       case 0x0B: return TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA;
712       case 0x0C: return TLS_DH_DSS_WITH_DES_CBC_SHA;
713       case 0x0D: return TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA;
714       case 0x0E: return TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA;
715       case 0x0F: return TLS_DH_RSA_WITH_DES_CBC_SHA;
716       case 0x10: return TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA;
717       case 0x11: return TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA;
718       case 0x12: return TLS_DHE_DSS_WITH_DES_CBC_SHA;
719       case 0x13: return TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA;
720       case 0x14: return TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA;
721       case 0x15: return TLS_DHE_RSA_WITH_DES_CBC_SHA;
722       case 0x16: return TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA;
723       case 0x2F: return TLS_RSA_WITH_AES_128_CBC_SHA;
724       case 0x30: return TLS_DH_DSS_WITH_AES_128_CBC_SHA;
725       case 0x31: return TLS_DH_RSA_WITH_AES_128_CBC_SHA;
726       case 0x32: return TLS_DHE_DSS_WITH_AES_128_CBC_SHA;
727       case 0x33: return TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
728       case 0x35: return TLS_RSA_WITH_AES_256_CBC_SHA;
729       case 0x36: return TLS_DH_DSS_WITH_AES_256_CBC_SHA;
730       case 0x37: return TLS_DH_RSA_WITH_AES_256_CBC_SHA;
731       case 0x38: return TLS_DHE_DSS_WITH_AES_256_CBC_SHA;
732       case 0x39: return TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
733       /*case 0x50: return TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA;
734       case 0x51: return TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA;
735       case 0x52: return TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA;
736       case 0x53: return TLS_SRP_SHA_WITH_AES_128_CBC_SHA;
737       case 0x54: return TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA;
738       case 0x55: return TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA;
739       case 0x56: return TLS_SRP_SHA_WITH_AES_256_CBC_SHA;
740       case 0x57: return TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA;
741       case 0x58: return TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA;
742       case 0x70: return TLS_DHE_DSS_WITH_CAST_128_CBC_SHA;
743       case 0x71: return TLS_DHE_DSS_WITH_CAST_128_CBC_RMD;
744       case 0x72: return TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD;
745       case 0x73: return TLS_DHE_DSS_WITH_AES_128_CBC_RMD;
746       case 0x74: return TLS_DHE_DSS_WITH_AES_256_CBC_RMD;
747       case 0x75: return TLS_DHE_RSA_WITH_CAST_128_CBC_SHA;
748       case 0x76: return TLS_DHE_RSA_WITH_CAST_128_CBC_RMD;
749       case 0x77: return TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD;
750       case 0x78: return TLS_DHE_RSA_WITH_AES_128_CBC_RMD;
751       case 0x79: return TLS_DHE_RSA_WITH_AES_256_CBC_RMD;
752       case 0x7A: return TLS_RSA_WITH_CAST_128_CBC_SHA;
753       case 0x7B: return TLS_RSA_WITH_CAST_128_CBC_RMD;
754       case 0x7C: return TLS_RSA_WITH_3DES_EDE_CBC_RMD;
755       case 0x7D: return TLS_RSA_WITH_AES_128_CBC_RMD;
756       case 0x7E: return TLS_RSA_WITH_AES_256_CBC_RMD;*/
757       case 0x8A: return TLS_PSK_WITH_RC4_128_SHA;
758       case 0x8B: return TLS_PSK_WITH_3DES_EDE_CBC_SHA;
759       case 0x8C: return TLS_PSK_WITH_AES_128_CBC_SHA;
760       case 0x8D: return TLS_PSK_WITH_AES_256_CBC_SHA;
761       case 0x8E: return TLS_DHE_PSK_WITH_RC4_128_SHA;
762       case 0x8F: return TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA;
763       case 0x90: return TLS_DHE_PSK_WITH_AES_128_CBC_SHA;
764       case 0x91: return TLS_DHE_PSK_WITH_AES_256_CBC_SHA;
765       case 0x92: return TLS_RSA_PSK_WITH_RC4_128_SHA;
766       case 0x93: return TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA;
767       case 0x94: return TLS_RSA_PSK_WITH_AES_128_CBC_SHA;
768       case 0x95: return TLS_RSA_PSK_WITH_AES_256_CBC_SHA;
769       }
770     return this;
771   }
772 
isResolved()773   public boolean isResolved()
774   {
775     return isResolved;
776   }
777 
keyLength()778   public int keyLength()
779   {
780     return keyLength;
781   }
782 
isExportable()783   public boolean isExportable()
784   {
785     return exportable;
786   }
787 
isStreamCipher()788   public boolean isStreamCipher()
789   {
790     return isStream;
791   }
792 
793 //   String getAuthType()
794 //   {
795 //     if (keyExchangeAlgorithm == KeyExchangeAlgorithm.RSA)
796 //       {
797 //         if (isExportable())
798 //           {
799 //             return "RSA_EXPORT";
800 //           }
801 //         return "RSA";
802 //       }
803 //     return kexName + "_" + sigName;
804 //   }
805 
id()806   public byte[] id()
807   {
808     return id;
809   }
810 
equals(Object o)811   public boolean equals(Object o)
812   {
813     if (!(o instanceof CipherSuite))
814       {
815         return false;
816       }
817     if (o == this)
818       return true;
819     byte[] id = ((CipherSuite) o).id();
820     return (id[0] == this.id[0] &&
821             id[1] == this.id[1]);
822   }
823 
hashCode()824   public int hashCode()
825   {
826     return 0xFFFF0000 | (id[0] & 0xFF) << 8 | (id[1] & 0xFF);
827   }
828 
toString(String prefix)829   public String toString (String prefix)
830   {
831     return toString ();
832   }
833 
toString()834   public String toString()
835   {
836     if (name == null)
837       {
838         return "{ " + (id[0] & 0xFF) + ", " + (id[1] & 0xFF) + " }";
839       }
840     return name;
841   }
842 
isCBCMode()843   public boolean isCBCMode()
844   {
845     return isCBCMode;
846   }
847 
848 }
849