1 package org.bouncycastle.jsse.provider;
2 
3 import java.util.Collections;
4 import java.util.HashSet;
5 import java.util.Set;
6 
7 import org.bouncycastle.tls.CipherSuite;
8 import org.bouncycastle.tls.CipherType;
9 import org.bouncycastle.tls.EncryptionAlgorithm;
10 import org.bouncycastle.tls.KeyExchangeAlgorithm;
11 import org.bouncycastle.tls.MACAlgorithm;
12 import org.bouncycastle.tls.TlsUtils;
13 import org.bouncycastle.tls.crypto.CryptoHashAlgorithm;
14 
15 class CipherSuiteInfo
16 {
forCipherSuite(int cipherSuite, String name)17     static CipherSuiteInfo forCipherSuite(int cipherSuite, String name)
18     {
19         if (!name.startsWith("TLS_"))
20         {
21             throw new IllegalArgumentException();
22         }
23 
24         int encryptionAlgorithm = TlsUtils.getEncryptionAlgorithm(cipherSuite);
25         int encryptionAlgorithmType = TlsUtils.getEncryptionAlgorithmType(encryptionAlgorithm);
26         int cryptoHashAlgorithm = getCryptoHashAlgorithm(cipherSuite);
27         int keyExchangeAlgorithm = TlsUtils.getKeyExchangeAlgorithm(cipherSuite);
28         int macAlgorithm = TlsUtils.getMACAlgorithm(cipherSuite);
29 
30         Set<String> decompositionX509 = new HashSet<String>();
31         decomposeKeyExchangeAlgorithm(decompositionX509, keyExchangeAlgorithm);
32 
33         Set<String> decompositionTLS = new HashSet<String>(decompositionX509);
34         decomposeEncryptionAlgorithm(decompositionTLS, encryptionAlgorithm);
35         decomposeHashAlgorithm(decompositionTLS, cryptoHashAlgorithm);
36         decomposeMACAlgorithm(decompositionTLS, encryptionAlgorithmType, macAlgorithm);
37 
38         boolean isTLSv13 = (KeyExchangeAlgorithm.NULL == keyExchangeAlgorithm);
39 
40         return new CipherSuiteInfo(cipherSuite, name, isTLSv13, Collections.unmodifiableSet(decompositionTLS),
41             Collections.unmodifiableSet(decompositionX509));
42     }
43 
44     private final int cipherSuite;
45     private final String name;
46     private final boolean isTLSv13;
47     private final Set<String> decompositionTLS, decompositionX509;
48 
CipherSuiteInfo(int cipherSuite, String name, boolean isTLSv13, Set<String> decompositionTLS, Set<String> decompositionX509)49     private CipherSuiteInfo(int cipherSuite, String name, boolean isTLSv13, Set<String> decompositionTLS,
50         Set<String> decompositionX509)
51     {
52         this.cipherSuite = cipherSuite;
53         this.name = name;
54         this.isTLSv13 = isTLSv13;
55         this.decompositionTLS = decompositionTLS;
56         this.decompositionX509 = decompositionX509;
57     }
58 
getCipherSuite()59     public int getCipherSuite()
60     {
61         return cipherSuite;
62     }
63 
getDecompositionTLS()64     public Set<String> getDecompositionTLS()
65     {
66         return decompositionTLS;
67     }
68 
getDecompositionX509()69     public Set<String> getDecompositionX509()
70     {
71         return decompositionX509;
72     }
73 
getName()74     public String getName()
75     {
76         return name;
77     }
78 
isTLSv13()79     boolean isTLSv13()
80     {
81         return isTLSv13;
82     }
83 
addAll(Set<String> decomposition, String... entries)84     private static void addAll(Set<String> decomposition, String... entries)
85     {
86         for (String entry : entries)
87         {
88             decomposition.add(entry);
89         }
90     }
91 
decomposeEncryptionAlgorithm(Set<String> decomposition, int encryptionAlgorithm)92     private static void decomposeEncryptionAlgorithm(Set<String> decomposition, int encryptionAlgorithm)
93     {
94         String transformation = getTransformation(encryptionAlgorithm);
95         decomposition.addAll(JcaAlgorithmDecomposer.INSTANCE_JCA.decompose(transformation));
96 
97         switch (encryptionAlgorithm)
98         {
99         case EncryptionAlgorithm._3DES_EDE_CBC:
100             decomposition.add("3DES_EDE_CBC");
101             break;
102         case EncryptionAlgorithm.AES_128_CBC:
103             decomposition.add("AES_128_CBC");
104             break;
105         case EncryptionAlgorithm.AES_128_CCM:
106             decomposition.add("AES_128_CCM");
107             break;
108         case EncryptionAlgorithm.AES_128_CCM_8:
109             decomposition.add("AES_128_CCM_8");
110             break;
111         case EncryptionAlgorithm.AES_128_GCM:
112             decomposition.add("AES_128_GCM");
113             break;
114         case EncryptionAlgorithm.AES_256_CBC:
115             decomposition.add("AES_256_CBC");
116             break;
117         case EncryptionAlgorithm.AES_256_CCM:
118             decomposition.add("AES_256_CCM");
119             break;
120         case EncryptionAlgorithm.AES_256_CCM_8:
121             decomposition.add("AES_256_CCM_8");
122             break;
123         case EncryptionAlgorithm.AES_256_GCM:
124             decomposition.add("AES_256_GCM");
125             break;
126         case EncryptionAlgorithm.ARIA_128_CBC:
127             decomposition.add("ARIA_128_CBC");
128             break;
129         case EncryptionAlgorithm.ARIA_256_CBC:
130             decomposition.add("ARIA_256_CBC");
131             break;
132         case EncryptionAlgorithm.ARIA_128_GCM:
133             decomposition.add("ARIA_128_GCM");
134             break;
135         case EncryptionAlgorithm.ARIA_256_GCM:
136             decomposition.add("ARIA_256_GCM");
137             break;
138         case EncryptionAlgorithm.CAMELLIA_128_CBC:
139             decomposition.add("CAMELLIA_128_CBC");
140             break;
141         case EncryptionAlgorithm.CAMELLIA_256_CBC:
142             decomposition.add("CAMELLIA_256_CBC");
143             break;
144         case EncryptionAlgorithm.CAMELLIA_128_GCM:
145             decomposition.add("CAMELLIA_128_GCM");
146             break;
147         case EncryptionAlgorithm.CAMELLIA_256_GCM:
148             decomposition.add("CAMELLIA_256_GCM");
149             break;
150         case EncryptionAlgorithm.CHACHA20_POLY1305:
151             // NOTE: Following SunJSSE, nothing beyond the transformation added above (i.e "ChaCha20-Poly1305")
152             break;
153         case EncryptionAlgorithm.NULL:
154             decomposition.add("C_NULL");
155             break;
156         case EncryptionAlgorithm.SM4_CBC:
157             decomposition.add("SM4_CBC");
158             break;
159         case EncryptionAlgorithm.SM4_CCM:
160             decomposition.add("SM4_CCM");
161             break;
162         case EncryptionAlgorithm.SM4_GCM:
163             decomposition.add("SM4_GCM");
164             break;
165         default:
166             throw new IllegalArgumentException();
167         }
168     }
169 
decomposeHashAlgorithm(Set<String> decomposition, int cryptoHashAlgorithm)170     private static void decomposeHashAlgorithm(Set<String> decomposition, int cryptoHashAlgorithm)
171     {
172         switch (cryptoHashAlgorithm)
173         {
174         case CryptoHashAlgorithm.sha256:
175             addAll(decomposition, "SHA256", "SHA-256", "HmacSHA256");
176             break;
177         case CryptoHashAlgorithm.sha384:
178             addAll(decomposition, "SHA384", "SHA-384", "HmacSHA384");
179             break;
180 //        case CryptoHashAlgorithm.sha512:
181 //            addAll(decomposition, "SHA512", "SHA-512", "HmacSHA512");
182 //            break;
183         case CryptoHashAlgorithm.sm3:
184             addAll(decomposition, "SM3", "HmacSM3");
185             break;
186         default:
187             throw new IllegalArgumentException();
188         }
189     }
190 
decomposeKeyExchangeAlgorithm(Set<String> decomposition, int keyExchangeAlgorithm)191     private static void decomposeKeyExchangeAlgorithm(Set<String> decomposition, int keyExchangeAlgorithm)
192     {
193         switch (keyExchangeAlgorithm)
194         {
195         case KeyExchangeAlgorithm.DHE_DSS:
196             addAll(decomposition, "DSA", "DSS", "DH", "DHE", "DiffieHellman", "DHE_DSS");
197             break;
198         case KeyExchangeAlgorithm.DHE_RSA:
199             addAll(decomposition, "RSA", "DH", "DHE", "DiffieHellman", "DHE_RSA");
200             break;
201         case KeyExchangeAlgorithm.ECDHE_ECDSA:
202             addAll(decomposition, "ECDHE", "ECDSA", "ECDHE_ECDSA");
203             break;
204         case KeyExchangeAlgorithm.ECDHE_RSA:
205             addAll(decomposition, "ECDHE", "RSA", "ECDHE_RSA");
206             break;
207         case KeyExchangeAlgorithm.NULL:
208             // NOTE: TLS 1.3 cipher suites
209             break;
210         case KeyExchangeAlgorithm.RSA:
211             addAll(decomposition, "RSA");
212             break;
213         default:
214             throw new IllegalArgumentException();
215         }
216     }
217 
decomposeMACAlgorithm(Set<String> decomposition, int cipherType, int macAlgorithm)218     private static void decomposeMACAlgorithm(Set<String> decomposition, int cipherType, int macAlgorithm)
219     {
220         switch (macAlgorithm)
221         {
222         case MACAlgorithm._null:
223             if (CipherType.aead != cipherType)
224             {
225                 addAll(decomposition, "M_NULL");
226             }
227             break;
228         case MACAlgorithm.hmac_md5:
229             addAll(decomposition, "MD5", "HmacMD5");
230             break;
231         case MACAlgorithm.hmac_sha1:
232             addAll(decomposition, "SHA1", "SHA-1", "HmacSHA1");
233             break;
234         case MACAlgorithm.hmac_sha256:
235             addAll(decomposition, "SHA256", "SHA-256", "HmacSHA256");
236             break;
237         case MACAlgorithm.hmac_sha384:
238             addAll(decomposition, "SHA384", "SHA-384", "HmacSHA384");
239             break;
240 //        case MACAlgorithm.hmac_sha512:
241 //            addAll(decomposition, "SHA512", "SHA-512", "HmacSHA512");
242 //            break;
243         default:
244             throw new IllegalArgumentException();
245         }
246     }
247 
getCryptoHashAlgorithm(int cipherSuite)248     private static int getCryptoHashAlgorithm(int cipherSuite)
249     {
250         switch (cipherSuite)
251         {
252         case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
253         case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
254         case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
255         case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA:
256         case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA:
257         case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
258         case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
259         case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
260         case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
261         case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
262         case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
263         case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
264         case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
265         case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA:
266         case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
267         case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
268         case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
269         case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA:
270         case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA:
271         case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
272         case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
273         case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
274         case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
275         case CipherSuite.TLS_RSA_WITH_NULL_SHA:
276             /*
277              * TODO[jsse] We follow SunJSSE behaviour here, but it's not quite right; these cipher
278              * suites will actually use the legacy PRF based on MD5/SHA1 for TLS 1.1 or earlier.
279              */
280             return CryptoHashAlgorithm.sha256;
281 
282         case CipherSuite.TLS_AES_128_CCM_SHA256:
283         case CipherSuite.TLS_AES_128_CCM_8_SHA256:
284         case CipherSuite.TLS_AES_128_GCM_SHA256:
285         case CipherSuite.TLS_CHACHA20_POLY1305_SHA256:
286         case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
287         case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
288         case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
289         case CipherSuite.TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256:
290         case CipherSuite.TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256:
291         case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256:
292         case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256:
293         case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256:
294         case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
295         case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM:
296         case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8:
297         case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
298         case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
299         case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM:
300         case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8:
301         case CipherSuite.TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256:
302         case CipherSuite.TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256:
303         case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
304         case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
305         case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
306         case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
307         case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
308         case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
309         case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
310         case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
311         case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
312         case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
313         case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256:
314         case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256:
315         case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
316         case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
317         case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
318         case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
319         case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
320         case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256:
321         case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256:
322         case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
323         case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
324         case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
325         case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
326         case CipherSuite.TLS_RSA_WITH_AES_128_CCM:
327         case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8:
328         case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256:
329         case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
330         case CipherSuite.TLS_RSA_WITH_AES_256_CCM:
331         case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8:
332         case CipherSuite.TLS_RSA_WITH_ARIA_128_CBC_SHA256:
333         case CipherSuite.TLS_RSA_WITH_ARIA_128_GCM_SHA256:
334         case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
335         case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256:
336         case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
337         case CipherSuite.TLS_RSA_WITH_NULL_SHA256:
338             return CryptoHashAlgorithm.sha256;
339 
340         case CipherSuite.TLS_AES_256_GCM_SHA384:
341         case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
342         case CipherSuite.TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384:
343         case CipherSuite.TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384:
344         case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384:
345         case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
346         case CipherSuite.TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384:
347         case CipherSuite.TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384:
348         case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
349         case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
350         case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
351         case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384:
352         case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384:
353         case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
354         case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
355         case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
356         case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
357         case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384:
358         case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384:
359         case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384:
360         case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
361         case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384:
362         case CipherSuite.TLS_RSA_WITH_ARIA_256_CBC_SHA384:
363         case CipherSuite.TLS_RSA_WITH_ARIA_256_GCM_SHA384:
364         case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384:
365             return CryptoHashAlgorithm.sha384;
366 
367         case CipherSuite.TLS_SM4_CCM_SM3:
368         case CipherSuite.TLS_SM4_GCM_SM3:
369             return CryptoHashAlgorithm.sm3;
370 
371         default:
372             throw new IllegalArgumentException();
373         }
374     }
375 
getTransformation(int encryptionAlgorithm)376     private static String getTransformation(int encryptionAlgorithm)
377     {
378         switch (encryptionAlgorithm)
379         {
380         case EncryptionAlgorithm._3DES_EDE_CBC:
381             return "DESede/CBC/NoPadding";
382         case EncryptionAlgorithm.AES_128_CBC:
383         case EncryptionAlgorithm.AES_256_CBC:
384             return "AES/CBC/NoPadding";
385         case EncryptionAlgorithm.AES_128_CCM:
386         case EncryptionAlgorithm.AES_128_CCM_8:
387         case EncryptionAlgorithm.AES_256_CCM:
388         case EncryptionAlgorithm.AES_256_CCM_8:
389             return "AES/CCM/NoPadding";
390         case EncryptionAlgorithm.AES_128_GCM:
391         case EncryptionAlgorithm.AES_256_GCM:
392             return "AES/GCM/NoPadding";
393         case EncryptionAlgorithm.ARIA_128_CBC:
394         case EncryptionAlgorithm.ARIA_256_CBC:
395             return "ARIA/CBC/NoPadding";
396         case EncryptionAlgorithm.ARIA_128_GCM:
397         case EncryptionAlgorithm.ARIA_256_GCM:
398             return "ARIA/GCM/NoPadding";
399         case EncryptionAlgorithm.CAMELLIA_128_CBC:
400         case EncryptionAlgorithm.CAMELLIA_256_CBC:
401             return "Camellia/CBC/NoPadding";
402         case EncryptionAlgorithm.CAMELLIA_128_GCM:
403         case EncryptionAlgorithm.CAMELLIA_256_GCM:
404             return "Camellia/GCM/NoPadding";
405         case EncryptionAlgorithm.CHACHA20_POLY1305:
406             return "ChaCha20-Poly1305";
407         case EncryptionAlgorithm.NULL:
408             return "NULL";
409         case EncryptionAlgorithm.SM4_CBC:
410             return "SM4/CBC/NoPadding";
411         case EncryptionAlgorithm.SM4_CCM:
412             return "SM4/CCM/NoPadding";
413         case EncryptionAlgorithm.SM4_GCM:
414             return "SM4/GCM/NoPadding";
415         default:
416             throw new IllegalArgumentException();
417         }
418     }
419 }
420