1 /*
2  * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package sun.security.ssl;
27 
28 import java.io.IOException;
29 import java.util.AbstractMap.SimpleImmutableEntry;
30 import java.util.Arrays;
31 import java.util.HashMap;
32 import java.util.Map;
33 import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
34 import sun.security.ssl.X509Authentication.X509Possession;
35 
36 final class SSLKeyExchange implements SSLKeyAgreementGenerator,
37         SSLHandshakeBinding {
38     private final SSLAuthentication authentication;
39     private final SSLKeyAgreement keyAgreement;
40 
SSLKeyExchange(X509Authentication authentication, SSLKeyAgreement keyAgreement)41     SSLKeyExchange(X509Authentication authentication,
42             SSLKeyAgreement keyAgreement) {
43         this.authentication = authentication;
44         this.keyAgreement = keyAgreement;
45     }
46 
createPossessions(HandshakeContext context)47     SSLPossession[] createPossessions(HandshakeContext context) {
48         // authentication
49         SSLPossession authPossession = null;
50         if (authentication != null) {
51             authPossession = authentication.createPossession(context);
52             if (authPossession == null) {
53                 return new SSLPossession[0];
54             } else if (context instanceof ServerHandshakeContext) {
55                 // The authentication information may be used further for
56                 // key agreement parameters negotiation.
57                 ServerHandshakeContext shc = (ServerHandshakeContext)context;
58                 shc.interimAuthn = authPossession;
59             }
60         }
61 
62         // key agreement
63         SSLPossession kaPossession;
64         if (keyAgreement == T12KeyAgreement.RSA_EXPORT) {
65             // a special case
66             X509Possession x509Possession = (X509Possession)authPossession;
67             if (JsseJce.getRSAKeyLength(
68                     x509Possession.popCerts[0].getPublicKey()) > 512) {
69                 kaPossession = keyAgreement.createPossession(context);
70 
71                 if (kaPossession == null) {
72                     return new SSLPossession[0];
73                 } else {
74                     return authentication != null ?
75                             new SSLPossession[] {authPossession, kaPossession} :
76                             new SSLPossession[] {kaPossession};
77                 }
78             } else {
79                 return authentication != null ?
80                         new SSLPossession[] {authPossession} :
81                         new SSLPossession[0];
82             }
83         } else {
84             kaPossession = keyAgreement.createPossession(context);
85             if (kaPossession == null) {
86                 // special cases
87                 if (keyAgreement == T12KeyAgreement.RSA ||
88                         keyAgreement == T12KeyAgreement.ECDH) {
89                     return authentication != null ?
90                             new SSLPossession[] {authPossession} :
91                             new SSLPossession[0];
92                 } else {
93                     return new SSLPossession[0];
94                 }
95             } else {
96                 return authentication != null ?
97                         new SSLPossession[] {authPossession, kaPossession} :
98                         new SSLPossession[] {kaPossession};
99             }
100         }
101     }
102 
103     @Override
createKeyDerivation( HandshakeContext handshakeContext)104     public SSLKeyDerivation createKeyDerivation(
105             HandshakeContext handshakeContext) throws IOException {
106         return keyAgreement.createKeyDerivation(handshakeContext);
107     }
108 
109     @Override
getRelatedHandshakers( HandshakeContext handshakeContext)110     public SSLHandshake[] getRelatedHandshakers(
111             HandshakeContext handshakeContext) {
112         SSLHandshake[] auHandshakes;
113         if (authentication != null) {
114             auHandshakes =
115                 authentication.getRelatedHandshakers(handshakeContext);
116         } else {
117             auHandshakes = null;
118         }
119 
120         SSLHandshake[] kaHandshakes =
121                 keyAgreement.getRelatedHandshakers(handshakeContext);
122 
123         if (auHandshakes == null || auHandshakes.length == 0) {
124             return kaHandshakes;
125         } else if (kaHandshakes == null || kaHandshakes.length == 0) {
126             return auHandshakes;
127         } else {
128             SSLHandshake[] producers = Arrays.copyOf(
129                      auHandshakes, auHandshakes.length + kaHandshakes.length);
130             System.arraycopy(kaHandshakes, 0,
131                     producers, auHandshakes.length, kaHandshakes.length);
132             return producers;
133         }
134     }
135 
136     @Override
getHandshakeProducers( HandshakeContext handshakeContext)137     public Map.Entry<Byte, HandshakeProducer>[] getHandshakeProducers(
138             HandshakeContext handshakeContext) {
139         Map.Entry<Byte, HandshakeProducer>[] auProducers;
140         if (authentication != null) {
141             auProducers =
142                 authentication.getHandshakeProducers(handshakeContext);
143         } else {
144             auProducers = null;
145         }
146 
147         Map.Entry<Byte, HandshakeProducer>[] kaProducers =
148                 keyAgreement.getHandshakeProducers(handshakeContext);
149 
150         if (auProducers == null || auProducers.length == 0) {
151             return kaProducers;
152         } else if (kaProducers == null || kaProducers.length == 0) {
153             return auProducers;
154         } else {
155             Map.Entry<Byte, HandshakeProducer>[] producers = Arrays.copyOf(
156                      auProducers, auProducers.length + kaProducers.length);
157             System.arraycopy(kaProducers, 0,
158                     producers, auProducers.length, kaProducers.length);
159             return producers;
160         }
161     }
162 
163     @Override
getHandshakeConsumers( HandshakeContext handshakeContext)164     public Map.Entry<Byte, SSLConsumer>[] getHandshakeConsumers(
165             HandshakeContext handshakeContext) {
166         Map.Entry<Byte, SSLConsumer>[] auConsumers;
167         if (authentication != null) {
168             auConsumers =
169                 authentication.getHandshakeConsumers(handshakeContext);
170         } else {
171             auConsumers = null;
172         }
173 
174         Map.Entry<Byte, SSLConsumer>[] kaConsumers =
175                 keyAgreement.getHandshakeConsumers(handshakeContext);
176 
177         if (auConsumers == null || auConsumers.length == 0) {
178             return kaConsumers;
179         } else if (kaConsumers == null || kaConsumers.length == 0) {
180             return auConsumers;
181         } else {
182             Map.Entry<Byte, SSLConsumer>[] producers = Arrays.copyOf(
183                      auConsumers, auConsumers.length + kaConsumers.length);
184             System.arraycopy(kaConsumers, 0,
185                     producers, auConsumers.length, kaConsumers.length);
186             return producers;
187         }
188     }
189 
190     // SSL 3.0 - (D)TLS 1.2
valueOf( CipherSuite.KeyExchange keyExchange, ProtocolVersion protocolVersion)191     static SSLKeyExchange valueOf(
192             CipherSuite.KeyExchange keyExchange,
193             ProtocolVersion protocolVersion) {
194         if (keyExchange == null || protocolVersion == null) {
195             return null;
196         }
197 
198         switch (keyExchange) {
199             case K_RSA:
200                 return SSLKeyExRSA.KE;
201             case K_RSA_EXPORT:
202                 return SSLKeyExRSAExport.KE;
203             case K_DHE_DSS:
204                 return SSLKeyExDHEDSS.KE;
205             case K_DHE_DSS_EXPORT:
206                 return SSLKeyExDHEDSSExport.KE;
207             case K_DHE_RSA:
208                 if (protocolVersion.useTLS12PlusSpec()) {   // (D)TLS 1.2
209                     return SSLKeyExDHERSAOrPSS.KE;
210                 } else {    // SSL 3.0, TLS 1.0/1.1
211                     return SSLKeyExDHERSA.KE;
212                 }
213             case K_DHE_RSA_EXPORT:
214                 return SSLKeyExDHERSAExport.KE;
215             case K_DH_ANON:
216                 return SSLKeyExDHANON.KE;
217             case K_DH_ANON_EXPORT:
218                 return SSLKeyExDHANONExport.KE;
219             case K_ECDH_ECDSA:
220                 return SSLKeyExECDHECDSA.KE;
221             case K_ECDH_RSA:
222                 return SSLKeyExECDHRSA.KE;
223             case K_ECDHE_ECDSA:
224                 return SSLKeyExECDHEECDSA.KE;
225             case K_ECDHE_RSA:
226                 if (protocolVersion.useTLS12PlusSpec()) {   // (D)TLS 1.2
227                     return SSLKeyExECDHERSAOrPSS.KE;
228                 } else {    // SSL 3.0, TLS 1.0/1.1
229                     return SSLKeyExECDHERSA.KE;
230                 }
231             case K_ECDH_ANON:
232                 return SSLKeyExECDHANON.KE;
233         }
234 
235         return null;
236     }
237 
238     // TLS 1.3
valueOf(NamedGroup namedGroup)239     static SSLKeyExchange valueOf(NamedGroup namedGroup) {
240         SSLKeyAgreement ka = T13KeyAgreement.valueOf(namedGroup);
241         if (ka != null) {
242             return new SSLKeyExchange(null, ka);
243         }
244 
245         return null;
246     }
247 
248     private static class SSLKeyExRSA {
249         private static SSLKeyExchange KE = new SSLKeyExchange(
250                 X509Authentication.RSA, T12KeyAgreement.RSA);
251     }
252 
253     private static class SSLKeyExRSAExport {
254         private static SSLKeyExchange KE = new SSLKeyExchange(
255                 X509Authentication.RSA, T12KeyAgreement.RSA_EXPORT);
256     }
257 
258     private static class SSLKeyExDHEDSS {
259         private static SSLKeyExchange KE = new SSLKeyExchange(
260                 X509Authentication.DSA, T12KeyAgreement.DHE);
261     }
262 
263     private static class SSLKeyExDHEDSSExport {
264         private static SSLKeyExchange KE = new SSLKeyExchange(
265                 X509Authentication.DSA, T12KeyAgreement.DHE_EXPORT);
266     }
267 
268     private static class SSLKeyExDHERSA {
269         private static SSLKeyExchange KE = new SSLKeyExchange(
270                 X509Authentication.RSA, T12KeyAgreement.DHE);
271     }
272 
273     private static class SSLKeyExDHERSAOrPSS {
274         private static SSLKeyExchange KE = new SSLKeyExchange(
275                 X509Authentication.RSA_OR_PSS, T12KeyAgreement.DHE);
276     }
277 
278     private static class SSLKeyExDHERSAExport {
279         private static SSLKeyExchange KE = new SSLKeyExchange(
280                 X509Authentication.RSA, T12KeyAgreement.DHE_EXPORT);
281     }
282 
283     private static class SSLKeyExDHANON {
284         private static SSLKeyExchange KE = new SSLKeyExchange(
285                 null, T12KeyAgreement.DHE);
286     }
287 
288     private static class SSLKeyExDHANONExport {
289         private static SSLKeyExchange KE = new SSLKeyExchange(
290                 null, T12KeyAgreement.DHE_EXPORT);
291     }
292 
293     private static class SSLKeyExECDHECDSA {
294         private static SSLKeyExchange KE = new SSLKeyExchange(
295                 X509Authentication.EC, T12KeyAgreement.ECDH);
296     }
297 
298     private static class SSLKeyExECDHRSA {
299         private static SSLKeyExchange KE = new SSLKeyExchange(
300                 X509Authentication.EC, T12KeyAgreement.ECDH);
301     }
302 
303     private static class SSLKeyExECDHEECDSA {
304         private static SSLKeyExchange KE = new SSLKeyExchange(
305                 X509Authentication.EC, T12KeyAgreement.ECDHE);
306     }
307 
308     private static class SSLKeyExECDHERSA {
309         private static SSLKeyExchange KE = new SSLKeyExchange(
310                 X509Authentication.RSA, T12KeyAgreement.ECDHE);
311     }
312 
313     private static class SSLKeyExECDHERSAOrPSS {
314         private static SSLKeyExchange KE = new SSLKeyExchange(
315                 X509Authentication.RSA_OR_PSS, T12KeyAgreement.ECDHE);
316     }
317 
318     private static class SSLKeyExECDHANON {
319         private static SSLKeyExchange KE = new SSLKeyExchange(
320                 null, T12KeyAgreement.ECDHE);
321     }
322 
323     private enum T12KeyAgreement implements SSLKeyAgreement {
324         RSA             ("rsa",         null,
325                                         RSAKeyExchange.kaGenerator),
326         RSA_EXPORT      ("rsa_export",  RSAKeyExchange.poGenerator,
327                                         RSAKeyExchange.kaGenerator),
328         DHE             ("dhe",         DHKeyExchange.poGenerator,
329                                         DHKeyExchange.kaGenerator),
330         DHE_EXPORT      ("dhe_export",  DHKeyExchange.poExportableGenerator,
331                                         DHKeyExchange.kaGenerator),
332         ECDH            ("ecdh",        null,
333                                         ECDHKeyExchange.ecdhKAGenerator),
334         ECDHE           ("ecdhe",       ECDHKeyExchange.poGenerator,
335                                         ECDHKeyExchange.ecdheXdhKAGenerator);
336 
337         final String name;
338         final SSLPossessionGenerator possessionGenerator;
339         final SSLKeyAgreementGenerator keyAgreementGenerator;
340 
T12KeyAgreement(String name, SSLPossessionGenerator possessionGenerator, SSLKeyAgreementGenerator keyAgreementGenerator)341         T12KeyAgreement(String name,
342                 SSLPossessionGenerator possessionGenerator,
343                 SSLKeyAgreementGenerator keyAgreementGenerator) {
344             this.name = name;
345             this.possessionGenerator = possessionGenerator;
346             this.keyAgreementGenerator = keyAgreementGenerator;
347         }
348 
349         @Override
createPossession(HandshakeContext context)350         public SSLPossession createPossession(HandshakeContext context) {
351             if (possessionGenerator != null) {
352                 return possessionGenerator.createPossession(context);
353             }
354 
355             return null;
356         }
357 
358         @Override
createKeyDerivation( HandshakeContext context)359         public SSLKeyDerivation createKeyDerivation(
360                 HandshakeContext context) throws IOException {
361             return keyAgreementGenerator.createKeyDerivation(context);
362         }
363 
364         @Override
getRelatedHandshakers( HandshakeContext handshakeContext)365         public SSLHandshake[] getRelatedHandshakers(
366                 HandshakeContext handshakeContext) {
367             if (!handshakeContext.negotiatedProtocol.useTLS13PlusSpec()) {
368                 if (this.possessionGenerator != null) {
369                     return new SSLHandshake[] {
370                             SSLHandshake.SERVER_KEY_EXCHANGE
371                         };
372                 }
373             }
374 
375             return new SSLHandshake[0];
376         }
377 
378         @Override
379         @SuppressWarnings({"unchecked", "rawtypes"})
getHandshakeProducers( HandshakeContext handshakeContext)380         public Map.Entry<Byte, HandshakeProducer>[] getHandshakeProducers(
381                 HandshakeContext handshakeContext) {
382             if (handshakeContext.negotiatedProtocol.useTLS13PlusSpec()) {
383                 return (Map.Entry<Byte, HandshakeProducer>[])(new Map.Entry[0]);
384             }
385 
386             if (handshakeContext.sslConfig.isClientMode) {
387                 switch (this) {
388                     case RSA:
389                     case RSA_EXPORT:
390                         return (Map.Entry<Byte,
391                                 HandshakeProducer>[])(new Map.Entry[] {
392                             new SimpleImmutableEntry<>(
393                                     SSLHandshake.CLIENT_KEY_EXCHANGE.id,
394                                     RSAClientKeyExchange.rsaHandshakeProducer
395                             )
396                         });
397 
398                     case DHE:
399                     case DHE_EXPORT:
400                         return (Map.Entry<Byte,
401                                 HandshakeProducer>[])(new Map.Entry[] {
402                             new SimpleImmutableEntry<Byte, HandshakeProducer>(
403                                     SSLHandshake.CLIENT_KEY_EXCHANGE.id,
404                                     DHClientKeyExchange.dhHandshakeProducer
405                             )
406                         });
407 
408                     case ECDH:
409                         return (Map.Entry<Byte,
410                                 HandshakeProducer>[])(new Map.Entry[] {
411                             new SimpleImmutableEntry<>(
412                                 SSLHandshake.CLIENT_KEY_EXCHANGE.id,
413                                 ECDHClientKeyExchange.ecdhHandshakeProducer
414                             )
415                         });
416 
417                     case ECDHE:
418                         return (Map.Entry<Byte,
419                                 HandshakeProducer>[])(new Map.Entry[] {
420                             new SimpleImmutableEntry<>(
421                                 SSLHandshake.CLIENT_KEY_EXCHANGE.id,
422                                 ECDHClientKeyExchange.ecdheHandshakeProducer
423                             )
424                         });
425                 }
426             } else {
427                 switch (this) {
428                     case RSA_EXPORT:
429                         return (Map.Entry<Byte,
430                                 HandshakeProducer>[])(new Map.Entry[] {
431                             new SimpleImmutableEntry<>(
432                                     SSLHandshake.SERVER_KEY_EXCHANGE.id,
433                                     RSAServerKeyExchange.rsaHandshakeProducer
434                             )
435                         });
436 
437                     case DHE:
438                     case DHE_EXPORT:
439                         return (Map.Entry<Byte,
440                                 HandshakeProducer>[])(new Map.Entry[] {
441                             new SimpleImmutableEntry<>(
442                                     SSLHandshake.SERVER_KEY_EXCHANGE.id,
443                                     DHServerKeyExchange.dhHandshakeProducer
444                             )
445                         });
446 
447                     case ECDHE:
448                         return (Map.Entry<Byte,
449                                 HandshakeProducer>[])(new Map.Entry[] {
450                             new SimpleImmutableEntry<>(
451                                     SSLHandshake.SERVER_KEY_EXCHANGE.id,
452                                     ECDHServerKeyExchange.ecdheHandshakeProducer
453                             )
454                         });
455                 }
456             }
457 
458             return (Map.Entry<Byte, HandshakeProducer>[])(new Map.Entry[0]);
459         }
460 
461         @Override
462         @SuppressWarnings({"unchecked", "rawtypes"})
getHandshakeConsumers( HandshakeContext handshakeContext)463         public Map.Entry<Byte, SSLConsumer>[] getHandshakeConsumers(
464                 HandshakeContext handshakeContext) {
465             if (handshakeContext.negotiatedProtocol.useTLS13PlusSpec()) {
466                 return (Map.Entry<Byte, SSLConsumer>[])(new Map.Entry[0]);
467             }
468 
469             if (handshakeContext.sslConfig.isClientMode) {
470                 switch (this) {
471                     case RSA_EXPORT:
472                         return (Map.Entry<Byte,
473                                 SSLConsumer>[])(new Map.Entry[] {
474                             new SimpleImmutableEntry<>(
475                                     SSLHandshake.SERVER_KEY_EXCHANGE.id,
476                                     RSAServerKeyExchange.rsaHandshakeConsumer
477                             )
478                         });
479 
480                     case DHE:
481                     case DHE_EXPORT:
482                         return (Map.Entry<Byte,
483                                 SSLConsumer>[])(new Map.Entry[] {
484                             new SimpleImmutableEntry<>(
485                                     SSLHandshake.SERVER_KEY_EXCHANGE.id,
486                                     DHServerKeyExchange.dhHandshakeConsumer
487                             )
488                         });
489 
490                     case ECDHE:
491                         return (Map.Entry<Byte,
492                                 SSLConsumer>[])(new Map.Entry[] {
493                             new SimpleImmutableEntry<>(
494                                     SSLHandshake.SERVER_KEY_EXCHANGE.id,
495                                     ECDHServerKeyExchange.ecdheHandshakeConsumer
496                             )
497                         });
498                 }
499             } else {
500                 switch (this) {
501                     case RSA:
502                     case RSA_EXPORT:
503                         return (Map.Entry<Byte,
504                                 SSLConsumer>[])(new Map.Entry[] {
505                             new SimpleImmutableEntry<>(
506                                     SSLHandshake.CLIENT_KEY_EXCHANGE.id,
507                                     RSAClientKeyExchange.rsaHandshakeConsumer
508                             )
509                         });
510 
511                     case DHE:
512                     case DHE_EXPORT:
513                         return (Map.Entry<Byte,
514                                 SSLConsumer>[])(new Map.Entry[] {
515                             new SimpleImmutableEntry<>(
516                                     SSLHandshake.CLIENT_KEY_EXCHANGE.id,
517                                     DHClientKeyExchange.dhHandshakeConsumer
518                             )
519                         });
520 
521                     case ECDH:
522                         return (Map.Entry<Byte,
523                                 SSLConsumer>[])(new Map.Entry[] {
524                             new SimpleImmutableEntry<>(
525                                 SSLHandshake.CLIENT_KEY_EXCHANGE.id,
526                                 ECDHClientKeyExchange.ecdhHandshakeConsumer
527                             )
528                         });
529 
530                     case ECDHE:
531                         return (Map.Entry<Byte,
532                                 SSLConsumer>[])(new Map.Entry[] {
533                             new SimpleImmutableEntry<>(
534                                 SSLHandshake.CLIENT_KEY_EXCHANGE.id,
535                                 ECDHClientKeyExchange.ecdheHandshakeConsumer
536                             )
537                         });
538                 }
539             }
540 
541             return (Map.Entry<Byte, SSLConsumer>[])(new Map.Entry[0]);
542         }
543     }
544 
545     private static final class T13KeyAgreement implements SSLKeyAgreement {
546         private final NamedGroup namedGroup;
547         static final Map<NamedGroup, T13KeyAgreement>
548                 supportedKeyShares = new HashMap<>();
549 
550         static {
551             for (NamedGroup namedGroup :
552                     SupportedGroups.supportedNamedGroups) {
supportedKeyShares.put( namedGroup, new T13KeyAgreement(namedGroup))553                 supportedKeyShares.put(
554                         namedGroup, new T13KeyAgreement(namedGroup));
555             }
556         }
557 
T13KeyAgreement(NamedGroup namedGroup)558         private T13KeyAgreement(NamedGroup namedGroup) {
559             this.namedGroup = namedGroup;
560         }
561 
valueOf(NamedGroup namedGroup)562         static T13KeyAgreement valueOf(NamedGroup namedGroup) {
563             return supportedKeyShares.get(namedGroup);
564         }
565 
566         @Override
createPossession(HandshakeContext hc)567         public SSLPossession createPossession(HandshakeContext hc) {
568             return namedGroup.createPossession(hc.sslContext.getSecureRandom());
569         }
570 
571         @Override
createKeyDerivation( HandshakeContext hc)572         public SSLKeyDerivation createKeyDerivation(
573                 HandshakeContext hc) throws IOException {
574             return namedGroup.createKeyDerivation(hc);
575         }
576     }
577 }
578