1 /* 2 * Copyright (c) 2015, 2020, 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.PrivateKey; 31 import java.security.cert.X509Certificate; 32 import java.text.MessageFormat; 33 import java.util.ArrayList; 34 import java.util.Collection; 35 import java.util.Collections; 36 import java.util.HashSet; 37 import java.util.LinkedList; 38 import java.util.List; 39 import java.util.Locale; 40 import javax.net.ssl.SSLEngine; 41 import javax.net.ssl.SSLSocket; 42 import javax.net.ssl.X509ExtendedKeyManager; 43 import javax.security.auth.x500.X500Principal; 44 import sun.security.ssl.CipherSuite.KeyExchange; 45 import sun.security.ssl.SSLHandshake.HandshakeMessage; 46 import sun.security.ssl.X509Authentication.X509Possession; 47 48 /** 49 * Pack of the CertificateRequest handshake message. 50 */ 51 final class CertificateRequest { 52 static final SSLConsumer t10HandshakeConsumer = 53 new T10CertificateRequestConsumer(); 54 static final HandshakeProducer t10HandshakeProducer = 55 new T10CertificateRequestProducer(); 56 57 static final SSLConsumer t12HandshakeConsumer = 58 new T12CertificateRequestConsumer(); 59 static final HandshakeProducer t12HandshakeProducer = 60 new T12CertificateRequestProducer(); 61 62 static final SSLConsumer t13HandshakeConsumer = 63 new T13CertificateRequestConsumer(); 64 static final HandshakeProducer t13HandshakeProducer = 65 new T13CertificateRequestProducer(); 66 67 // TLS 1.2 and prior versions 68 private static enum ClientCertificateType { 69 // RFC 2246 70 RSA_SIGN ((byte)0x01, "rsa_sign", "RSA", true), 71 DSS_SIGN ((byte)0x02, "dss_sign", "DSA", true), 72 RSA_FIXED_DH ((byte)0x03, "rsa_fixed_dh"), 73 DSS_FIXED_DH ((byte)0x04, "dss_fixed_dh"), 74 75 // RFC 4346 76 RSA_EPHEMERAL_DH ((byte)0x05, "rsa_ephemeral_dh"), 77 DSS_EPHEMERAL_DH ((byte)0x06, "dss_ephemeral_dh"), 78 FORTEZZA_DMS ((byte)0x14, "fortezza_dms"), 79 80 // RFC 4492 81 ECDSA_SIGN ((byte)0x40, "ecdsa_sign", 82 "EC", JsseJce.isEcAvailable()), 83 RSA_FIXED_ECDH ((byte)0x41, "rsa_fixed_ecdh"), 84 ECDSA_FIXED_ECDH ((byte)0x42, "ecdsa_fixed_ecdh"); 85 86 private static final byte[] CERT_TYPES = 87 JsseJce.isEcAvailable() ? new byte[] { 88 ECDSA_SIGN.id, 89 RSA_SIGN.id, 90 DSS_SIGN.id 91 } : new byte[] { 92 RSA_SIGN.id, 93 DSS_SIGN.id 94 }; 95 96 final byte id; 97 final String name; 98 final String keyAlgorithm; 99 final boolean isAvailable; 100 101 private ClientCertificateType(byte id, String name) { 102 this(id, name, null, false); 103 } 104 105 private ClientCertificateType(byte id, String name, 106 String keyAlgorithm, boolean isAvailable) { 107 this.id = id; 108 this.name = name; 109 this.keyAlgorithm = keyAlgorithm; 110 this.isAvailable = isAvailable; 111 } 112 113 private static String nameOf(byte id) { 114 for (ClientCertificateType cct : ClientCertificateType.values()) { 115 if (cct.id == id) { 116 return cct.name; 117 } 118 } 119 return "UNDEFINED-CLIENT-CERTIFICATE-TYPE(" + (int)id + ")"; 120 } 121 122 private static ClientCertificateType valueOf(byte id) { 123 for (ClientCertificateType cct : ClientCertificateType.values()) { 124 if (cct.id == id) { 125 return cct; 126 } 127 } 128 129 return null; 130 } 131 132 private static String[] getKeyTypes(byte[] ids) { 133 ArrayList<String> keyTypes = new ArrayList<>(3); 134 for (byte id : ids) { 135 ClientCertificateType cct = ClientCertificateType.valueOf(id); 136 if (cct.isAvailable) { 137 keyTypes.add(cct.keyAlgorithm); 138 } 139 } 140 141 return keyTypes.toArray(new String[0]); 142 } 143 } 144 145 /** 146 * The "CertificateRequest" handshake message for SSL 3.0 and TLS 1.0/1.1. 147 */ 148 static final class T10CertificateRequestMessage extends HandshakeMessage { 149 final byte[] types; // certificate types 150 final List<byte[]> authorities; // certificate authorities 151 152 T10CertificateRequestMessage(HandshakeContext handshakeContext, 153 X509Certificate[] trustedCerts, KeyExchange keyExchange) { 154 super(handshakeContext); 155 156 this.authorities = new ArrayList<>(trustedCerts.length); 157 for (X509Certificate cert : trustedCerts) { 158 X500Principal x500Principal = cert.getSubjectX500Principal(); 159 authorities.add(x500Principal.getEncoded()); 160 } 161 162 this.types = ClientCertificateType.CERT_TYPES; 163 } 164 165 T10CertificateRequestMessage(HandshakeContext handshakeContext, 166 ByteBuffer m) throws IOException { 167 super(handshakeContext); 168 169 // struct { 170 // ClientCertificateType certificate_types<1..2^8-1>; 171 // DistinguishedName certificate_authorities<0..2^16-1>; 172 // } CertificateRequest; 173 if (m.remaining() < 4) { 174 throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, 175 "Incorrect CertificateRequest message: no sufficient data"); 176 } 177 this.types = Record.getBytes8(m); 178 179 int listLen = Record.getInt16(m); 180 if (listLen > m.remaining()) { 181 throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, 182 "Incorrect CertificateRequest message:no sufficient data"); 183 } 184 185 if (listLen > 0) { 186 this.authorities = new LinkedList<>(); 187 while (listLen > 0) { 188 // opaque DistinguishedName<1..2^16-1>; 189 byte[] encoded = Record.getBytes16(m); 190 listLen -= (2 + encoded.length); 191 authorities.add(encoded); 192 } 193 } else { 194 this.authorities = Collections.emptyList(); 195 } 196 } 197 198 String[] getKeyTypes() { 199 return ClientCertificateType.getKeyTypes(types); 200 } 201 202 X500Principal[] getAuthorities() { 203 X500Principal[] principals = new X500Principal[authorities.size()]; 204 int i = 0; 205 for (byte[] encoded : authorities) { 206 principals[i++] = new X500Principal(encoded); 207 } 208 209 return principals; 210 } 211 212 @Override 213 public SSLHandshake handshakeType() { 214 return SSLHandshake.CERTIFICATE_REQUEST; 215 } 216 217 @Override 218 public int messageLength() { 219 int len = 1 + types.length + 2; 220 for (byte[] encoded : authorities) { 221 len += encoded.length + 2; 222 } 223 return len; 224 } 225 226 @Override 227 public void send(HandshakeOutStream hos) throws IOException { 228 hos.putBytes8(types); 229 230 int listLen = 0; 231 for (byte[] encoded : authorities) { 232 listLen += encoded.length + 2; 233 } 234 235 hos.putInt16(listLen); 236 for (byte[] encoded : authorities) { 237 hos.putBytes16(encoded); 238 } 239 } 240 241 @Override 242 public String toString() { 243 MessageFormat messageFormat = new MessageFormat( 244 "\"CertificateRequest\": '{'\n" + 245 " \"certificate types\": {0}\n" + 246 " \"certificate authorities\": {1}\n" + 247 "'}'", 248 Locale.ENGLISH); 249 250 List<String> typeNames = new ArrayList<>(types.length); 251 for (byte type : types) { 252 typeNames.add(ClientCertificateType.nameOf(type)); 253 } 254 255 List<String> authorityNames = new ArrayList<>(authorities.size()); 256 for (byte[] encoded : authorities) { 257 X500Principal principal = new X500Principal(encoded); 258 authorityNames.add(principal.toString()); 259 } 260 Object[] messageFields = { 261 typeNames, 262 authorityNames 263 }; 264 265 return messageFormat.format(messageFields); 266 } 267 } 268 269 /** 270 * The "CertificateRequest" handshake message producer for SSL 3.0 and 271 * TLS 1.0/1.1. 272 */ 273 private static final 274 class T10CertificateRequestProducer implements HandshakeProducer { 275 // Prevent instantiation of this class. 276 private T10CertificateRequestProducer() { 277 // blank 278 } 279 280 @Override 281 public byte[] produce(ConnectionContext context, 282 HandshakeMessage message) throws IOException { 283 // The producing happens in server side only. 284 ServerHandshakeContext shc = (ServerHandshakeContext)context; 285 286 X509Certificate[] caCerts = 287 shc.sslContext.getX509TrustManager().getAcceptedIssuers(); 288 T10CertificateRequestMessage crm = new T10CertificateRequestMessage( 289 shc, caCerts, shc.negotiatedCipherSuite.keyExchange); 290 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 291 SSLLogger.fine( 292 "Produced CertificateRequest handshake message", crm); 293 } 294 295 // Output the handshake message. 296 crm.write(shc.handshakeOutput); 297 shc.handshakeOutput.flush(); 298 299 // 300 // update 301 // 302 shc.handshakeConsumers.put(SSLHandshake.CERTIFICATE.id, 303 SSLHandshake.CERTIFICATE); 304 shc.handshakeConsumers.put(SSLHandshake.CERTIFICATE_VERIFY.id, 305 SSLHandshake.CERTIFICATE_VERIFY); 306 307 // The handshake message has been delivered. 308 return null; 309 } 310 } 311 312 /** 313 * The "CertificateRequest" handshake message consumer for SSL 3.0 and 314 * TLS 1.0/1.1. 315 */ 316 private static final 317 class T10CertificateRequestConsumer implements SSLConsumer { 318 // Prevent instantiation of this class. 319 private T10CertificateRequestConsumer() { 320 // blank 321 } 322 323 @Override 324 public void consume(ConnectionContext context, 325 ByteBuffer message) throws IOException { 326 // The consuming happens in client side only. 327 ClientHandshakeContext chc = (ClientHandshakeContext)context; 328 329 // clean up this consumer 330 chc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_REQUEST.id); 331 332 SSLConsumer certStatCons = chc.handshakeConsumers.remove( 333 SSLHandshake.CERTIFICATE_STATUS.id); 334 if (certStatCons != null) { 335 // Stapling was active but no certificate status message 336 // was sent. We need to run the absence handler which will 337 // check the certificate chain. 338 CertificateStatus.handshakeAbsence.absent(context, null); 339 } 340 341 T10CertificateRequestMessage crm = 342 new T10CertificateRequestMessage(chc, message); 343 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 344 SSLLogger.fine( 345 "Consuming CertificateRequest handshake message", crm); 346 } 347 348 // 349 // validate 350 // 351 // blank 352 353 // 354 // update 355 // 356 357 // An empty client Certificate handshake message may be allow. 358 chc.handshakeProducers.put(SSLHandshake.CERTIFICATE.id, 359 SSLHandshake.CERTIFICATE); 360 361 X509ExtendedKeyManager km = chc.sslContext.getX509KeyManager(); 362 String clientAlias = null; 363 if (chc.conContext.transport instanceof SSLSocketImpl) { 364 clientAlias = km.chooseClientAlias(crm.getKeyTypes(), 365 crm.getAuthorities(), (SSLSocket)chc.conContext.transport); 366 } else if (chc.conContext.transport instanceof SSLEngineImpl) { 367 clientAlias = km.chooseEngineClientAlias(crm.getKeyTypes(), 368 crm.getAuthorities(), (SSLEngine)chc.conContext.transport); 369 } 370 371 372 if (clientAlias == null) { 373 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 374 SSLLogger.warning("No available client authentication"); 375 } 376 return; 377 } 378 379 PrivateKey clientPrivateKey = km.getPrivateKey(clientAlias); 380 if (clientPrivateKey == null) { 381 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 382 SSLLogger.warning("No available client private key"); 383 } 384 return; 385 } 386 387 X509Certificate[] clientCerts = km.getCertificateChain(clientAlias); 388 if ((clientCerts == null) || (clientCerts.length == 0)) { 389 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 390 SSLLogger.warning("No available client certificate"); 391 } 392 return; 393 } 394 395 chc.handshakePossessions.add( 396 new X509Possession(clientPrivateKey, clientCerts)); 397 chc.handshakeProducers.put(SSLHandshake.CERTIFICATE_VERIFY.id, 398 SSLHandshake.CERTIFICATE_VERIFY); 399 } 400 } 401 402 /** 403 * The CertificateRequest handshake message for TLS 1.2. 404 */ 405 static final class T12CertificateRequestMessage extends HandshakeMessage { 406 final byte[] types; // certificate types 407 final int[] algorithmIds; // supported signature algorithms 408 final List<byte[]> authorities; // certificate authorities 409 410 T12CertificateRequestMessage(HandshakeContext handshakeContext, 411 X509Certificate[] trustedCerts, KeyExchange keyExchange, 412 List<SignatureScheme> signatureSchemes) throws IOException { 413 super(handshakeContext); 414 415 this.types = ClientCertificateType.CERT_TYPES; 416 417 if (signatureSchemes == null || signatureSchemes.isEmpty()) { 418 throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, 419 "No signature algorithms specified for " + 420 "CertificateRequest hanshake message"); 421 } 422 this.algorithmIds = new int[signatureSchemes.size()]; 423 int i = 0; 424 for (SignatureScheme scheme : signatureSchemes) { 425 algorithmIds[i++] = scheme.id; 426 } 427 428 this.authorities = new ArrayList<>(trustedCerts.length); 429 for (X509Certificate cert : trustedCerts) { 430 X500Principal x500Principal = cert.getSubjectX500Principal(); 431 authorities.add(x500Principal.getEncoded()); 432 } 433 } 434 435 T12CertificateRequestMessage(HandshakeContext handshakeContext, 436 ByteBuffer m) throws IOException { 437 super(handshakeContext); 438 439 // struct { 440 // ClientCertificateType certificate_types<1..2^8-1>; 441 // SignatureAndHashAlgorithm 442 // supported_signature_algorithms<2..2^16-2>; 443 // DistinguishedName certificate_authorities<0..2^16-1>; 444 // } CertificateRequest; 445 446 // certificate_authorities 447 if (m.remaining() < 8) { 448 throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, 449 "Invalid CertificateRequest handshake message: " + 450 "no sufficient data"); 451 } 452 this.types = Record.getBytes8(m); 453 454 // supported_signature_algorithms 455 if (m.remaining() < 6) { 456 throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, 457 "Invalid CertificateRequest handshake message: " + 458 "no sufficient data"); 459 } 460 461 byte[] algs = Record.getBytes16(m); 462 if (algs == null || algs.length == 0 || (algs.length & 0x01) != 0) { 463 throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, 464 "Invalid CertificateRequest handshake message: " + 465 "incomplete signature algorithms"); 466 } 467 468 this.algorithmIds = new int[(algs.length >> 1)]; 469 for (int i = 0, j = 0; i < algs.length;) { 470 byte hash = algs[i++]; 471 byte sign = algs[i++]; 472 algorithmIds[j++] = ((hash & 0xFF) << 8) | (sign & 0xFF); 473 } 474 475 // certificate_authorities 476 if (m.remaining() < 2) { 477 throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, 478 "Invalid CertificateRequest handshake message: " + 479 "no sufficient data"); 480 } 481 482 int listLen = Record.getInt16(m); 483 if (listLen > m.remaining()) { 484 throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, 485 "Invalid CertificateRequest message: no sufficient data"); 486 } 487 488 if (listLen > 0) { 489 this.authorities = new LinkedList<>(); 490 while (listLen > 0) { 491 // opaque DistinguishedName<1..2^16-1>; 492 byte[] encoded = Record.getBytes16(m); 493 listLen -= (2 + encoded.length); 494 authorities.add(encoded); 495 } 496 } else { 497 this.authorities = Collections.emptyList(); 498 } 499 } 500 501 String[] getKeyTypes() { 502 return ClientCertificateType.getKeyTypes(types); 503 } 504 505 X500Principal[] getAuthorities() { 506 X500Principal[] principals = new X500Principal[authorities.size()]; 507 int i = 0; 508 for (byte[] encoded : authorities) { 509 principals[i++] = new X500Principal(encoded); 510 } 511 512 return principals; 513 } 514 515 @Override 516 public SSLHandshake handshakeType() { 517 return SSLHandshake.CERTIFICATE_REQUEST; 518 } 519 520 @Override 521 public int messageLength() { 522 int len = 1 + types.length + 2 + (algorithmIds.length << 1) + 2; 523 for (byte[] encoded : authorities) { 524 len += encoded.length + 2; 525 } 526 return len; 527 } 528 529 @Override 530 public void send(HandshakeOutStream hos) throws IOException { 531 hos.putBytes8(types); 532 533 int listLen = 0; 534 for (byte[] encoded : authorities) { 535 listLen += encoded.length + 2; 536 } 537 538 hos.putInt16(algorithmIds.length << 1); 539 for (int algorithmId : algorithmIds) { 540 hos.putInt16(algorithmId); 541 } 542 543 hos.putInt16(listLen); 544 for (byte[] encoded : authorities) { 545 hos.putBytes16(encoded); 546 } 547 } 548 549 @Override 550 public String toString() { 551 MessageFormat messageFormat = new MessageFormat( 552 "\"CertificateRequest\": '{'\n" + 553 " \"certificate types\": {0}\n" + 554 " \"supported signature algorithms\": {1}\n" + 555 " \"certificate authorities\": {2}\n" + 556 "'}'", 557 Locale.ENGLISH); 558 559 List<String> typeNames = new ArrayList<>(types.length); 560 for (byte type : types) { 561 typeNames.add(ClientCertificateType.nameOf(type)); 562 } 563 564 List<String> algorithmNames = new ArrayList<>(algorithmIds.length); 565 for (int algorithmId : algorithmIds) { 566 algorithmNames.add(SignatureScheme.nameOf(algorithmId)); 567 } 568 569 List<String> authorityNames = new ArrayList<>(authorities.size()); 570 for (byte[] encoded : authorities) { 571 X500Principal principal = new X500Principal(encoded); 572 authorityNames.add(principal.toString()); 573 } 574 Object[] messageFields = { 575 typeNames, 576 algorithmNames, 577 authorityNames 578 }; 579 580 return messageFormat.format(messageFields); 581 } 582 } 583 584 /** 585 * The "CertificateRequest" handshake message producer for TLS 1.2. 586 */ 587 private static final 588 class T12CertificateRequestProducer implements HandshakeProducer { 589 // Prevent instantiation of this class. 590 private T12CertificateRequestProducer() { 591 // blank 592 } 593 594 @Override 595 public byte[] produce(ConnectionContext context, 596 HandshakeMessage message) throws IOException { 597 // The producing happens in server side only. 598 ServerHandshakeContext shc = (ServerHandshakeContext)context; 599 if (shc.localSupportedSignAlgs == null) { 600 shc.localSupportedSignAlgs = 601 SignatureScheme.getSupportedAlgorithms( 602 shc.sslConfig, 603 shc.algorithmConstraints, shc.activeProtocols); 604 } 605 606 if (shc.localSupportedSignAlgs == null || 607 shc.localSupportedSignAlgs.isEmpty()) { 608 throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE, 609 "No supported signature algorithm"); 610 } 611 612 X509Certificate[] caCerts = 613 shc.sslContext.getX509TrustManager().getAcceptedIssuers(); 614 T12CertificateRequestMessage crm = new T12CertificateRequestMessage( 615 shc, caCerts, shc.negotiatedCipherSuite.keyExchange, 616 shc.localSupportedSignAlgs); 617 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 618 SSLLogger.fine( 619 "Produced CertificateRequest handshake message", crm); 620 } 621 622 // Output the handshake message. 623 crm.write(shc.handshakeOutput); 624 shc.handshakeOutput.flush(); 625 626 // 627 // update 628 // 629 shc.handshakeConsumers.put(SSLHandshake.CERTIFICATE.id, 630 SSLHandshake.CERTIFICATE); 631 shc.handshakeConsumers.put(SSLHandshake.CERTIFICATE_VERIFY.id, 632 SSLHandshake.CERTIFICATE_VERIFY); 633 634 // The handshake message has been delivered. 635 return null; 636 } 637 } 638 639 /** 640 * The "CertificateRequest" handshake message consumer for TLS 1.2. 641 */ 642 private static final 643 class T12CertificateRequestConsumer implements SSLConsumer { 644 // Prevent instantiation of this class. 645 private T12CertificateRequestConsumer() { 646 // blank 647 } 648 649 @Override 650 public void consume(ConnectionContext context, 651 ByteBuffer message) throws IOException { 652 // The consuming happens in client side only. 653 ClientHandshakeContext chc = (ClientHandshakeContext)context; 654 655 // clean up this consumer 656 chc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_REQUEST.id); 657 658 SSLConsumer certStatCons = chc.handshakeConsumers.remove( 659 SSLHandshake.CERTIFICATE_STATUS.id); 660 if (certStatCons != null) { 661 // Stapling was active but no certificate status message 662 // was sent. We need to run the absence handler which will 663 // check the certificate chain. 664 CertificateStatus.handshakeAbsence.absent(context, null); 665 } 666 667 T12CertificateRequestMessage crm = 668 new T12CertificateRequestMessage(chc, message); 669 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 670 SSLLogger.fine( 671 "Consuming CertificateRequest handshake message", crm); 672 } 673 674 // 675 // validate 676 // 677 // blank 678 679 // 680 // update 681 // 682 683 // An empty client Certificate handshake message may be allow. 684 chc.handshakeProducers.put(SSLHandshake.CERTIFICATE.id, 685 SSLHandshake.CERTIFICATE); 686 687 List<SignatureScheme> sss = new LinkedList<>(); 688 for (int id : crm.algorithmIds) { 689 SignatureScheme ss = SignatureScheme.valueOf(id); 690 if (ss != null) { 691 sss.add(ss); 692 } 693 } 694 chc.peerRequestedSignatureSchemes = sss; 695 chc.peerRequestedCertSignSchemes = sss; // use the same schemes 696 chc.handshakeSession.setPeerSupportedSignatureAlgorithms(sss); 697 chc.peerSupportedAuthorities = crm.getAuthorities(); 698 699 // For TLS 1.2, we no longer use the certificate_types field 700 // from the CertificateRequest message to directly determine 701 // the SSLPossession. Instead, the choosePossession method 702 // will use the accepted signature schemes in the message to 703 // determine the set of acceptable certificate types to select from. 704 SSLPossession pos = choosePossession(chc); 705 if (pos == null) { 706 return; 707 } 708 709 chc.handshakePossessions.add(pos); 710 chc.handshakeProducers.put(SSLHandshake.CERTIFICATE_VERIFY.id, 711 SSLHandshake.CERTIFICATE_VERIFY); 712 } 713 714 private static SSLPossession choosePossession(HandshakeContext hc) 715 throws IOException { 716 if (hc.peerRequestedCertSignSchemes == null || 717 hc.peerRequestedCertSignSchemes.isEmpty()) { 718 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 719 SSLLogger.warning("No signature and hash algorithms " + 720 "in CertificateRequest"); 721 } 722 return null; 723 } 724 725 Collection<String> checkedKeyTypes = new HashSet<>(); 726 for (SignatureScheme ss : hc.peerRequestedCertSignSchemes) { 727 if (checkedKeyTypes.contains(ss.keyAlgorithm)) { 728 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 729 SSLLogger.warning( 730 "Unsupported authentication scheme: " + ss.name); 731 } 732 continue; 733 } 734 735 // Don't select a signature scheme unless we will be able to 736 // produce a CertificateVerify message later 737 if (SignatureScheme.getPreferableAlgorithm( 738 hc.algorithmConstraints, 739 hc.peerRequestedSignatureSchemes, 740 ss, hc.negotiatedProtocol) == null) { 741 742 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 743 SSLLogger.warning( 744 "Unable to produce CertificateVerify for " + 745 "signature scheme: " + ss.name); 746 } 747 checkedKeyTypes.add(ss.keyAlgorithm); 748 continue; 749 } 750 751 SSLAuthentication ka = X509Authentication.valueOf(ss); 752 if (ka == null) { 753 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 754 SSLLogger.warning( 755 "Unsupported authentication scheme: " + ss.name); 756 } 757 checkedKeyTypes.add(ss.keyAlgorithm); 758 continue; 759 } 760 761 SSLPossession pos = ka.createPossession(hc); 762 if (pos == null) { 763 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 764 SSLLogger.warning( 765 "Unavailable authentication scheme: " + ss.name); 766 } 767 continue; 768 } 769 770 return pos; 771 } 772 773 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 774 SSLLogger.warning("No available authentication scheme"); 775 } 776 return null; 777 } 778 } 779 780 /** 781 * The CertificateRequest handshake message for TLS 1.3. 782 */ 783 static final class T13CertificateRequestMessage extends HandshakeMessage { 784 private final byte[] requestContext; 785 private final SSLExtensions extensions; 786 787 T13CertificateRequestMessage( 788 HandshakeContext handshakeContext) throws IOException { 789 super(handshakeContext); 790 791 this.requestContext = new byte[0]; 792 this.extensions = new SSLExtensions(this); 793 } 794 795 T13CertificateRequestMessage(HandshakeContext handshakeContext, 796 ByteBuffer m) throws IOException { 797 super(handshakeContext); 798 799 // struct { 800 // opaque certificate_request_context<0..2^8-1>; 801 // Extension extensions<2..2^16-1>; 802 // } CertificateRequest; 803 if (m.remaining() < 5) { 804 throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, 805 "Invalid CertificateRequest handshake message: " + 806 "no sufficient data"); 807 } 808 this.requestContext = Record.getBytes8(m); 809 810 if (m.remaining() < 4) { 811 throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, 812 "Invalid CertificateRequest handshake message: " + 813 "no sufficient extensions data"); 814 } 815 SSLExtension[] enabledExtensions = 816 handshakeContext.sslConfig.getEnabledExtensions( 817 SSLHandshake.CERTIFICATE_REQUEST); 818 this.extensions = new SSLExtensions(this, m, enabledExtensions); 819 } 820 821 @Override 822 SSLHandshake handshakeType() { 823 return SSLHandshake.CERTIFICATE_REQUEST; 824 } 825 826 @Override 827 int messageLength() { 828 // In TLS 1.3, use of certain extensions is mandatory. 829 return 1 + requestContext.length + extensions.length(); 830 } 831 832 @Override 833 void send(HandshakeOutStream hos) throws IOException { 834 hos.putBytes8(requestContext); 835 836 // In TLS 1.3, use of certain extensions is mandatory. 837 extensions.send(hos); 838 } 839 840 @Override 841 public String toString() { 842 MessageFormat messageFormat = new MessageFormat( 843 "\"CertificateRequest\": '{'\n" + 844 " \"certificate_request_context\": \"{0}\",\n" + 845 " \"extensions\": [\n" + 846 "{1}\n" + 847 " ]\n" + 848 "'}'", 849 Locale.ENGLISH); 850 Object[] messageFields = { 851 Utilities.toHexString(requestContext), 852 Utilities.indent(Utilities.indent(extensions.toString())) 853 }; 854 855 return messageFormat.format(messageFields); 856 } 857 } 858 859 /** 860 * The "CertificateRequest" handshake message producer for TLS 1.3. 861 */ 862 private static final 863 class T13CertificateRequestProducer implements HandshakeProducer { 864 // Prevent instantiation of this class. 865 private T13CertificateRequestProducer() { 866 // blank 867 } 868 869 @Override 870 public byte[] produce(ConnectionContext context, 871 HandshakeMessage message) throws IOException { 872 // The producing happens in server side only. 873 ServerHandshakeContext shc = (ServerHandshakeContext)context; 874 875 T13CertificateRequestMessage crm = 876 new T13CertificateRequestMessage(shc); 877 // Produce extensions for CertificateRequest handshake message. 878 SSLExtension[] extTypes = shc.sslConfig.getEnabledExtensions( 879 SSLHandshake.CERTIFICATE_REQUEST, shc.negotiatedProtocol); 880 crm.extensions.produce(shc, extTypes); 881 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 882 SSLLogger.fine("Produced CertificateRequest message", crm); 883 } 884 885 // Output the handshake message. 886 crm.write(shc.handshakeOutput); 887 shc.handshakeOutput.flush(); 888 889 // 890 // update 891 // 892 shc.certRequestContext = crm.requestContext.clone(); 893 shc.handshakeConsumers.put(SSLHandshake.CERTIFICATE.id, 894 SSLHandshake.CERTIFICATE); 895 shc.handshakeConsumers.put(SSLHandshake.CERTIFICATE_VERIFY.id, 896 SSLHandshake.CERTIFICATE_VERIFY); 897 898 // The handshake message has been delivered. 899 return null; 900 } 901 } 902 903 /** 904 * The "CertificateRequest" handshake message consumer for TLS 1.3. 905 */ 906 private static final 907 class T13CertificateRequestConsumer implements SSLConsumer { 908 // Prevent instantiation of this class. 909 private T13CertificateRequestConsumer() { 910 // blank 911 } 912 913 @Override 914 public void consume(ConnectionContext context, 915 ByteBuffer message) throws IOException { 916 // The consuming happens in client side only. 917 ClientHandshakeContext chc = (ClientHandshakeContext)context; 918 919 // clean up this consumer 920 chc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_REQUEST.id); 921 922 T13CertificateRequestMessage crm = 923 new T13CertificateRequestMessage(chc, message); 924 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 925 SSLLogger.fine( 926 "Consuming CertificateRequest handshake message", crm); 927 } 928 929 // 930 // validate 931 // 932 SSLExtension[] extTypes = chc.sslConfig.getEnabledExtensions( 933 SSLHandshake.CERTIFICATE_REQUEST); 934 crm.extensions.consumeOnLoad(chc, extTypes); 935 936 // 937 // update 938 // 939 crm.extensions.consumeOnTrade(chc, extTypes); 940 941 // 942 // produce 943 // 944 chc.certRequestContext = crm.requestContext.clone(); 945 chc.handshakeProducers.put(SSLHandshake.CERTIFICATE.id, 946 SSLHandshake.CERTIFICATE); 947 chc.handshakeProducers.put(SSLHandshake.CERTIFICATE_VERIFY.id, 948 SSLHandshake.CERTIFICATE_VERIFY); 949 } 950 } 951 }