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