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