< prev index next >

src/java.base/share/classes/sun/security/ssl/KeyShareExtension.java

Print this page


   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.nio.ByteBuffer;

  30 import java.security.GeneralSecurityException;
  31 import java.text.MessageFormat;
  32 import java.util.Arrays;
  33 import java.util.Collections;

  34 import java.util.LinkedList;
  35 import java.util.List;
  36 import java.util.Locale;
  37 import java.util.Map;
  38 import javax.net.ssl.SSLProtocolException;




  39 import sun.security.ssl.KeyShareExtension.CHKeyShareSpec;
  40 import sun.security.ssl.SSLExtension.ExtensionConsumer;
  41 import sun.security.ssl.SSLExtension.SSLExtensionSpec;
  42 import sun.security.ssl.SSLHandshake.HandshakeMessage;


  43 import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
  44 import sun.security.util.HexDumpEncoder;
  45 
  46 /**
  47  * Pack of the "key_share" extensions.
  48  */
  49 final class KeyShareExtension {
  50     static final HandshakeProducer chNetworkProducer =
  51             new CHKeyShareProducer();
  52     static final ExtensionConsumer chOnLoadConsumer =
  53             new CHKeyShareConsumer();
  54     static final SSLStringizer chStringizer =
  55             new CHKeyShareStringizer();
  56 
  57     static final HandshakeProducer shNetworkProducer =
  58             new SHKeyShareProducer();
  59     static final ExtensionConsumer shOnLoadConsumer =
  60             new SHKeyShareConsumer();
  61     static final HandshakeAbsence shOnLoadAbsence =
  62             new SHKeyShareAbsence();


 239                     }
 240                     return null;
 241                 }
 242             }
 243 
 244             List<KeyShareEntry> keyShares = new LinkedList<>();
 245             for (NamedGroup ng : namedGroups) {
 246                 SSLKeyExchange ke = SSLKeyExchange.valueOf(ng);
 247                 if (ke == null) {
 248                     if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
 249                         SSLLogger.warning(
 250                             "No key exchange for named group " + ng.name);
 251                     }
 252                     continue;
 253                 }
 254 
 255                 SSLPossession[] poses = ke.createPossessions(chc);
 256                 for (SSLPossession pos : poses) {
 257                     // update the context
 258                     chc.handshakePossessions.add(pos);
 259                     if (!(pos instanceof NamedGroupPossession)) {

 260                         // May need more possesion types in the future.
 261                         continue;
 262                     }
 263 
 264                     keyShares.add(new KeyShareEntry(ng.id, pos.encode()));
 265                 }
 266 
 267                 // One key share entry only.  Too much key share entries makes
 268                 // the ClientHello handshake message really big.
 269                 if (!keyShares.isEmpty()) {
 270                     break;
 271                 }
 272             }
 273 
 274             int listLen = 0;
 275             for (KeyShareEntry entry : keyShares) {
 276                 listLen += entry.getEncodedSize();
 277             }
 278             byte[] extData = new byte[listLen + 2];     //  2: list length
 279             ByteBuffer m = ByteBuffer.wrap(extData);


 327             CHKeyShareSpec spec;
 328             try {
 329                 spec = new CHKeyShareSpec(buffer);
 330             } catch (IOException ioe) {
 331                 throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
 332             }
 333 
 334             List<SSLCredentials> credentials = new LinkedList<>();
 335             for (KeyShareEntry entry : spec.clientShares) {
 336                 NamedGroup ng = NamedGroup.valueOf(entry.namedGroupId);
 337                 if (ng == null || !SupportedGroups.isActivatable(
 338                         shc.sslConfig.algorithmConstraints, ng)) {
 339                     if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
 340                         SSLLogger.fine(
 341                                 "Ignore unsupported named group: " +
 342                                 NamedGroup.nameOf(entry.namedGroupId));
 343                     }
 344                     continue;
 345                 }
 346 
 347                 try {
 348                     SSLCredentials kaCred =
 349                         ng.decodeCredentials(entry.keyExchange,
 350                         shc.algorithmConstraints,
 351                         s -> SSLLogger.warning(s));
 352                     if (kaCred != null) {
 353                         credentials.add(kaCred);
































 354                     }
 355                 } catch (GeneralSecurityException ex) {
 356                     SSLLogger.warning(
 357                         "Cannot decode named group: " +
 358                         NamedGroup.nameOf(entry.namedGroupId));
 359                 }
 360             }
 361 
 362             if (!credentials.isEmpty()) {
 363                 shc.handshakeCredentials.addAll(credentials);
 364             } else {
 365                 // New handshake credentials are required from the client side.
 366                 shc.handshakeProducers.put(
 367                         SSLHandshake.HELLO_RETRY_REQUEST.id,
 368                         SSLHandshake.HELLO_RETRY_REQUEST);
 369             }
 370 
 371             // update the context
 372             shc.handshakeExtensions.put(SSLExtension.CH_KEY_SHARE, spec);
 373         }
 374     }
 375 
 376     /**
 377      * The key share entry used in ServerHello "key_share" extensions.
 378      */


 472                     SSLLogger.warning(
 473                             "Ignore, no available server key_share extension");
 474                 }
 475                 return null;
 476             }
 477 
 478             // use requested key share entries
 479             if ((shc.handshakeCredentials == null) ||
 480                     shc.handshakeCredentials.isEmpty()) {
 481                 // Unlikely, HelloRetryRequest should be used ealier.
 482                 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
 483                     SSLLogger.warning(
 484                             "No available client key share entries");
 485                 }
 486                 return null;
 487             }
 488 
 489             KeyShareEntry keyShare = null;
 490             for (SSLCredentials cd : shc.handshakeCredentials) {
 491                 NamedGroup ng = null;
 492                 if (cd instanceof NamedGroupCredentials) {
 493                     NamedGroupCredentials creds = (NamedGroupCredentials)cd;
 494                     ng = creds.getNamedGroup();

 495                 }
 496 
 497                 if (ng == null) {
 498                     continue;
 499                 }
 500 
 501                 SSLKeyExchange ke = SSLKeyExchange.valueOf(ng);
 502                 if (ke == null) {
 503                     if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
 504                         SSLLogger.warning(
 505                             "No key exchange for named group " + ng.name);
 506                     }
 507                     continue;
 508                 }
 509 
 510                 SSLPossession[] poses = ke.createPossessions(shc);
 511                 for (SSLPossession pos : poses) {
 512                     if (!(pos instanceof NamedGroupPossession)) {

 513                         // May need more possesion types in the future.
 514                         continue;
 515                     }
 516 
 517                     // update the context
 518                     shc.handshakeKeyExchange = ke;
 519                     shc.handshakePossessions.add(pos);
 520                     keyShare = new KeyShareEntry(ng.id, pos.encode());
 521                     break;
 522                 }
 523 
 524                 if (keyShare != null) {
 525                     for (Map.Entry<Byte, HandshakeProducer> me :
 526                             ke.getHandshakeProducers(shc)) {
 527                         shc.handshakeProducers.put(
 528                                 me.getKey(), me.getValue());
 529                     }
 530 
 531                     // We have got one! Don't forget to break.
 532                     break;
 533                 }
 534             }
 535 
 536             if (keyShare == null) {
 537                 // Unlikely, HelloRetryRequest should be used instead ealier.
 538                 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
 539                     SSLLogger.warning(
 540                             "No available server key_share extension");
 541                 }
 542                 return null;
 543             }
 544 
 545             byte[] extData = keyShare.getEncoded();
 546 
 547             // update the context
 548             SHKeyShareSpec spec = new SHKeyShareSpec(keyShare);
 549             shc.handshakeExtensions.put(SSLExtension.SH_KEY_SHARE, spec);
 550 
 551             return extData;


 587             } catch (IOException ioe) {
 588                 throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
 589             }
 590 
 591             KeyShareEntry keyShare = spec.serverShare;
 592             NamedGroup ng = NamedGroup.valueOf(keyShare.namedGroupId);
 593             if (ng == null || !SupportedGroups.isActivatable(
 594                     chc.sslConfig.algorithmConstraints, ng)) {
 595                 throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
 596                         "Unsupported named group: " +
 597                         NamedGroup.nameOf(keyShare.namedGroupId));
 598             }
 599 
 600             SSLKeyExchange ke = SSLKeyExchange.valueOf(ng);
 601             if (ke == null) {
 602                 throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
 603                         "No key exchange for named group " + ng.name);
 604             }
 605 
 606             SSLCredentials credentials = null;
 607             try {
 608                 SSLCredentials kaCred = ng.decodeCredentials(
 609                     keyShare.keyExchange, chc.algorithmConstraints,
 610                     s -> chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, s));
 611                 if (kaCred != null) {
 612                     credentials = kaCred;













 613                 }
 614             } catch (GeneralSecurityException ex) {




















 615                 throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
 616                         "Cannot decode named group: " +
 617                         NamedGroup.nameOf(keyShare.namedGroupId));
 618             }
 619 
 620             if (credentials == null) {
 621                 throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
 622                         "Unsupported named group: " + ng.name);
 623             }
 624 
 625             // update the context
 626             chc.handshakeKeyExchange = ke;
 627             chc.handshakeCredentials.add(credentials);
 628             chc.handshakeExtensions.put(SSLExtension.SH_KEY_SHARE, spec);
 629         }
 630     }
 631 
 632     /**
 633      * The absence processing if the extension is not present in
 634      * the ServerHello handshake message.
 635      */
 636     private static final class SHKeyShareAbsence implements HandshakeAbsence {


   1 /*
   2  * Copyright (c) 2015, 2018, 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.nio.ByteBuffer;
  30 import java.security.CryptoPrimitive;
  31 import java.security.GeneralSecurityException;
  32 import java.text.MessageFormat;
  33 import java.util.Arrays;
  34 import java.util.Collections;
  35 import java.util.EnumSet;
  36 import java.util.LinkedList;
  37 import java.util.List;
  38 import java.util.Locale;
  39 import java.util.Map;
  40 import javax.net.ssl.SSLProtocolException;
  41 import sun.security.ssl.DHKeyExchange.DHECredentials;
  42 import sun.security.ssl.DHKeyExchange.DHEPossession;
  43 import sun.security.ssl.ECDHKeyExchange.ECDHECredentials;
  44 import sun.security.ssl.ECDHKeyExchange.ECDHEPossession;
  45 import sun.security.ssl.KeyShareExtension.CHKeyShareSpec;
  46 import sun.security.ssl.SSLExtension.ExtensionConsumer;
  47 import sun.security.ssl.SSLExtension.SSLExtensionSpec;
  48 import sun.security.ssl.SSLHandshake.HandshakeMessage;
  49 import sun.security.ssl.SupportedGroupsExtension.NamedGroup;
  50 import sun.security.ssl.SupportedGroupsExtension.NamedGroupType;
  51 import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
  52 import sun.security.util.HexDumpEncoder;
  53 
  54 /**
  55  * Pack of the "key_share" extensions.
  56  */
  57 final class KeyShareExtension {
  58     static final HandshakeProducer chNetworkProducer =
  59             new CHKeyShareProducer();
  60     static final ExtensionConsumer chOnLoadConsumer =
  61             new CHKeyShareConsumer();
  62     static final SSLStringizer chStringizer =
  63             new CHKeyShareStringizer();
  64 
  65     static final HandshakeProducer shNetworkProducer =
  66             new SHKeyShareProducer();
  67     static final ExtensionConsumer shOnLoadConsumer =
  68             new SHKeyShareConsumer();
  69     static final HandshakeAbsence shOnLoadAbsence =
  70             new SHKeyShareAbsence();


 247                     }
 248                     return null;
 249                 }
 250             }
 251 
 252             List<KeyShareEntry> keyShares = new LinkedList<>();
 253             for (NamedGroup ng : namedGroups) {
 254                 SSLKeyExchange ke = SSLKeyExchange.valueOf(ng);
 255                 if (ke == null) {
 256                     if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
 257                         SSLLogger.warning(
 258                             "No key exchange for named group " + ng.name);
 259                     }
 260                     continue;
 261                 }
 262 
 263                 SSLPossession[] poses = ke.createPossessions(chc);
 264                 for (SSLPossession pos : poses) {
 265                     // update the context
 266                     chc.handshakePossessions.add(pos);
 267                     if (!(pos instanceof ECDHEPossession) &&
 268                             !(pos instanceof DHEPossession)) {
 269                         // May need more possesion types in the future.
 270                         continue;
 271                     }
 272 
 273                     keyShares.add(new KeyShareEntry(ng.id, pos.encode()));
 274                 }
 275 
 276                 // One key share entry only.  Too much key share entries makes
 277                 // the ClientHello handshake message really big.
 278                 if (!keyShares.isEmpty()) {
 279                     break;
 280                 }
 281             }
 282 
 283             int listLen = 0;
 284             for (KeyShareEntry entry : keyShares) {
 285                 listLen += entry.getEncodedSize();
 286             }
 287             byte[] extData = new byte[listLen + 2];     //  2: list length
 288             ByteBuffer m = ByteBuffer.wrap(extData);


 336             CHKeyShareSpec spec;
 337             try {
 338                 spec = new CHKeyShareSpec(buffer);
 339             } catch (IOException ioe) {
 340                 throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
 341             }
 342 
 343             List<SSLCredentials> credentials = new LinkedList<>();
 344             for (KeyShareEntry entry : spec.clientShares) {
 345                 NamedGroup ng = NamedGroup.valueOf(entry.namedGroupId);
 346                 if (ng == null || !SupportedGroups.isActivatable(
 347                         shc.sslConfig.algorithmConstraints, ng)) {
 348                     if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
 349                         SSLLogger.fine(
 350                                 "Ignore unsupported named group: " +
 351                                 NamedGroup.nameOf(entry.namedGroupId));
 352                     }
 353                     continue;
 354                 }
 355 
 356                 if (ng.type == NamedGroupType.NAMED_GROUP_ECDHE) {
 357                     try {
 358                         ECDHECredentials ecdhec =
 359                             ECDHECredentials.valueOf(ng, entry.keyExchange);
 360                         if (ecdhec != null) {
 361                             if (!shc.algorithmConstraints.permits(
 362                                     EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
 363                                     ecdhec.popPublicKey)) {
 364                                 SSLLogger.warning(
 365                                         "ECDHE key share entry does not " +
 366                                         "comply to algorithm constraints");
 367                             } else {
 368                                 credentials.add(ecdhec);
 369                             }
 370                         }
 371                     } catch (IOException | GeneralSecurityException ex) {
 372                         SSLLogger.warning(
 373                                 "Cannot decode named group: " +
 374                                 NamedGroup.nameOf(entry.namedGroupId));
 375                     }
 376                 } else if (ng.type == NamedGroupType.NAMED_GROUP_FFDHE) {
 377                     try {
 378                         DHECredentials dhec =
 379                                 DHECredentials.valueOf(ng, entry.keyExchange);
 380                         if (dhec != null) {
 381                             if (!shc.algorithmConstraints.permits(
 382                                     EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
 383                                     dhec.popPublicKey)) {
 384                                 SSLLogger.warning(
 385                                         "DHE key share entry does not " +
 386                                         "comply to algorithm constraints");
 387                             } else {
 388                                 credentials.add(dhec);
 389                             }
 390                         }
 391                     } catch (IOException | GeneralSecurityException ex) {
 392                         SSLLogger.warning(
 393                                 "Cannot decode named group: " +
 394                                 NamedGroup.nameOf(entry.namedGroupId));
 395                     }




 396                 }
 397             }
 398 
 399             if (!credentials.isEmpty()) {
 400                 shc.handshakeCredentials.addAll(credentials);
 401             } else {
 402                 // New handshake credentials are required from the client side.
 403                 shc.handshakeProducers.put(
 404                         SSLHandshake.HELLO_RETRY_REQUEST.id,
 405                         SSLHandshake.HELLO_RETRY_REQUEST);
 406             }
 407 
 408             // update the context
 409             shc.handshakeExtensions.put(SSLExtension.CH_KEY_SHARE, spec);
 410         }
 411     }
 412 
 413     /**
 414      * The key share entry used in ServerHello "key_share" extensions.
 415      */


 509                     SSLLogger.warning(
 510                             "Ignore, no available server key_share extension");
 511                 }
 512                 return null;
 513             }
 514 
 515             // use requested key share entries
 516             if ((shc.handshakeCredentials == null) ||
 517                     shc.handshakeCredentials.isEmpty()) {
 518                 // Unlikely, HelloRetryRequest should be used ealier.
 519                 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
 520                     SSLLogger.warning(
 521                             "No available client key share entries");
 522                 }
 523                 return null;
 524             }
 525 
 526             KeyShareEntry keyShare = null;
 527             for (SSLCredentials cd : shc.handshakeCredentials) {
 528                 NamedGroup ng = null;
 529                 if (cd instanceof ECDHECredentials) {
 530                     ng = ((ECDHECredentials)cd).namedGroup;
 531                 } else if (cd instanceof DHECredentials) {
 532                     ng = ((DHECredentials)cd).namedGroup;
 533                 }
 534 
 535                 if (ng == null) {
 536                     continue;
 537                 }
 538 
 539                 SSLKeyExchange ke = SSLKeyExchange.valueOf(ng);
 540                 if (ke == null) {
 541                     if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
 542                         SSLLogger.warning(
 543                             "No key exchange for named group " + ng.name);
 544                     }
 545                     continue;
 546                 }
 547 
 548                 SSLPossession[] poses = ke.createPossessions(shc);
 549                 for (SSLPossession pos : poses) {
 550                     if (!(pos instanceof ECDHEPossession) &&
 551                             !(pos instanceof DHEPossession)) {
 552                         // May need more possesion types in the future.
 553                         continue;
 554                     }
 555 
 556                     // update the context
 557                     shc.handshakeKeyExchange = ke;
 558                     shc.handshakePossessions.add(pos);
 559                     keyShare = new KeyShareEntry(ng.id, pos.encode());
 560                     break;
 561                 }
 562 
 563                 if (keyShare != null) {
 564                     for (Map.Entry<Byte, HandshakeProducer> me :
 565                             ke.getHandshakeProducers(shc)) {
 566                         shc.handshakeProducers.put(
 567                                 me.getKey(), me.getValue());
 568                     }
 569 
 570                     // We have got one! Don't forgor to break.
 571                     break;
 572                 }
 573             }
 574 
 575             if (keyShare == null) {
 576                 // Unlikely, HelloRetryRequest should be used instead ealier.
 577                 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
 578                     SSLLogger.warning(
 579                             "No available server key_share extension");
 580                 }
 581                 return null;
 582             }
 583 
 584             byte[] extData = keyShare.getEncoded();
 585 
 586             // update the context
 587             SHKeyShareSpec spec = new SHKeyShareSpec(keyShare);
 588             shc.handshakeExtensions.put(SSLExtension.SH_KEY_SHARE, spec);
 589 
 590             return extData;


 626             } catch (IOException ioe) {
 627                 throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
 628             }
 629 
 630             KeyShareEntry keyShare = spec.serverShare;
 631             NamedGroup ng = NamedGroup.valueOf(keyShare.namedGroupId);
 632             if (ng == null || !SupportedGroups.isActivatable(
 633                     chc.sslConfig.algorithmConstraints, ng)) {
 634                 throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
 635                         "Unsupported named group: " +
 636                         NamedGroup.nameOf(keyShare.namedGroupId));
 637             }
 638 
 639             SSLKeyExchange ke = SSLKeyExchange.valueOf(ng);
 640             if (ke == null) {
 641                 throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
 642                         "No key exchange for named group " + ng.name);
 643             }
 644 
 645             SSLCredentials credentials = null;
 646             if (ng.type == NamedGroupType.NAMED_GROUP_ECDHE) {
 647                 try {
 648                     ECDHECredentials ecdhec =
 649                             ECDHECredentials.valueOf(ng, keyShare.keyExchange);
 650                     if (ecdhec != null) {
 651                         if (!chc.algorithmConstraints.permits(
 652                                 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
 653                                 ecdhec.popPublicKey)) {
 654                             throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
 655                                     "ECDHE key share entry does not " +
 656                                     "comply to algorithm constraints");
 657                         } else {
 658                             credentials = ecdhec;
 659                         }
 660                     }
 661                 } catch (IOException | GeneralSecurityException ex) {
 662                     throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
 663                             "Cannot decode named group: " +
 664                             NamedGroup.nameOf(keyShare.namedGroupId));
 665                 }
 666             } else if (ng.type == NamedGroupType.NAMED_GROUP_FFDHE) {
 667                 try {
 668                     DHECredentials dhec =
 669                             DHECredentials.valueOf(ng, keyShare.keyExchange);
 670                     if (dhec != null) {
 671                         if (!chc.algorithmConstraints.permits(
 672                                 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
 673                                 dhec.popPublicKey)) {
 674                             throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
 675                                     "DHE key share entry does not " +
 676                                     "comply to algorithm constraints");
 677                         } else {
 678                             credentials = dhec;
 679                         }
 680                     }
 681                 } catch (IOException | GeneralSecurityException ex) {
 682                     throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
 683                             "Cannot decode named group: " +
 684                             NamedGroup.nameOf(keyShare.namedGroupId));
 685                 }
 686             } else {
 687                 throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
 688                         "Unsupported named group: " +
 689                         NamedGroup.nameOf(keyShare.namedGroupId));
 690             }
 691 
 692             if (credentials == null) {
 693                 throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
 694                         "Unsupported named group: " + ng.name);
 695             }
 696 
 697             // update the context
 698             chc.handshakeKeyExchange = ke;
 699             chc.handshakeCredentials.add(credentials);
 700             chc.handshakeExtensions.put(SSLExtension.SH_KEY_SHARE, spec);
 701         }
 702     }
 703 
 704     /**
 705      * The absence processing if the extension is not present in
 706      * the ServerHello handshake message.
 707      */
 708     private static final class SHKeyShareAbsence implements HandshakeAbsence {


< prev index next >