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