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 
  41     SSLKeyExchange(X509Authentication authentication,
  42             SSLKeyAgreement keyAgreement) {
  43         this.authentication = authentication;
  44         this.keyAgreement = keyAgreement;
  45     }
  46 
  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
 104     public SSLKeyDerivation createKeyDerivation(
 105             HandshakeContext handshakeContext) throws IOException {
 106         return keyAgreement.createKeyDerivation(handshakeContext);
 107     }
 108 
 109     @Override
 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
 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
 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
 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
 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 
 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
 350         public SSLPossession createPossession(HandshakeContext context) {
 351             if (possessionGenerator != null) {
 352                 return possessionGenerator.createPossession(context);
 353             }
 354 
 355             return null;
 356         }
 357 
 358         @Override
 359         public SSLKeyDerivation createKeyDerivation(
 360                 HandshakeContext context) throws IOException {
 361             return keyAgreementGenerator.createKeyDerivation(context);
 362         }
 363 
 364         @Override
 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"})
 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"})
 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) {
 553                 supportedKeyShares.put(
 554                         namedGroup, new T13KeyAgreement(namedGroup));
 555             }
 556         }
 557 
 558         private T13KeyAgreement(NamedGroup namedGroup) {
 559             this.namedGroup = namedGroup;
 560         }
 561 
 562         static T13KeyAgreement valueOf(NamedGroup namedGroup) {
 563             return supportedKeyShares.get(namedGroup);
 564         }
 565 
 566         @Override
 567         public SSLPossession createPossession(HandshakeContext hc) {
 568             return namedGroup.createPossession(hc.sslContext.getSecureRandom());
 569         }
 570 
 571         @Override
 572         public SSLKeyDerivation createKeyDerivation(
 573                 HandshakeContext hc) throws IOException {
 574             return namedGroup.createKeyDerivation(hc);
 575         }
 576     }
 577 }