That fuck shit the fascists are using
at master 800 lines 30 kB view raw
1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package org.conscrypt; 17 18import java.nio.ByteBuffer; 19import java.security.KeyManagementException; 20import java.security.PrivateKey; 21import java.security.Provider; 22import java.security.cert.X509Certificate; 23import javax.net.ssl.HostnameVerifier; 24import javax.net.ssl.HttpsURLConnection; 25import javax.net.ssl.SSLContext; 26import javax.net.ssl.SSLContextSpi; 27import javax.net.ssl.SSLEngine; 28import javax.net.ssl.SSLEngineResult; 29import javax.net.ssl.SSLException; 30import javax.net.ssl.SSLServerSocketFactory; 31import javax.net.ssl.SSLSession; 32import javax.net.ssl.SSLSessionContext; 33import javax.net.ssl.SSLSocket; 34import javax.net.ssl.SSLSocketFactory; 35import javax.net.ssl.TrustManager; 36import javax.net.ssl.X509TrustManager; 37 38/** 39 * Core API for creating and configuring all Conscrypt types. 40 * This is identical to the original Conscrypt.java, except with the slow 41 * version initialization code removed. 42 */ 43@SuppressWarnings("unused") 44public final class ConscryptSignal { 45 private ConscryptSignal() {} 46 47 /** 48 * Returns {@code true} if the Conscrypt native library has been successfully loaded. 49 */ 50 public static boolean isAvailable() { 51 try { 52 checkAvailability(); 53 return true; 54 } catch (Throwable e) { 55 return false; 56 } 57 } 58 59 // BEGIN MODIFICATION 60 /*public static class Version { 61 private final int major; 62 private final int minor; 63 private final int patch; 64 65 private Version(int major, int minor, int patch) { 66 this.major = major; 67 this.minor = minor; 68 this.patch = patch; 69 } 70 71 public int major() { return major; } 72 public int minor() { return minor; } 73 public int patch() { return patch; } 74 } 75 76 private static final Version VERSION; 77 78 static { 79 int major = -1; 80 int minor = -1; 81 int patch = -1; 82 InputStream stream = null; 83 try { 84 stream = Conscrypt.class.getResourceAsStream("conscrypt.properties"); 85 if (stream != null) { 86 Properties props = new Properties(); 87 props.load(stream); 88 major = Integer.parseInt(props.getProperty("org.conscrypt.version.major", "-1")); 89 minor = Integer.parseInt(props.getProperty("org.conscrypt.version.minor", "-1")); 90 patch = Integer.parseInt(props.getProperty("org.conscrypt.version.patch", "-1")); 91 } 92 } catch (IOException e) { 93 // TODO(prb): This should probably be fatal or have some fallback behaviour 94 } finally { 95 IoUtils.closeQuietly(stream); 96 } 97 if ((major >= 0) && (minor >= 0) && (patch >= 0)) { 98 VERSION = new Version(major, minor, patch); 99 } else { 100 VERSION = null; 101 } 102 } 103 104 /** 105 * Returns the version of this distribution of Conscrypt. If version information is 106 * unavailable, returns {@code null}. 107 */ 108 /*public static Version version() { 109 return VERSION; 110 }*/ 111 112 // END MODIFICATION 113 114 /** 115 * Checks that the Conscrypt support is available for the system. 116 * 117 * @throws UnsatisfiedLinkError if unavailable 118 */ 119 public static void checkAvailability() { 120 NativeCrypto.checkAvailability(); 121 } 122 123 /** 124 * Indicates whether the given {@link Provider} was created by this distribution of Conscrypt. 125 */ 126 public static boolean isConscrypt(Provider provider) { 127 return provider instanceof OpenSSLProvider; 128 } 129 130 /** 131 * Constructs a new {@link Provider} with the default name. 132 */ 133 public static Provider newProvider() { 134 checkAvailability(); 135 return new OpenSSLProvider(); 136 } 137 138 /** 139 * Constructs a new {@link Provider} with the given name. 140 * 141 * @deprecated Use {@link #newProviderBuilder()} instead. 142 */ 143 @Deprecated 144 public static Provider newProvider(String providerName) { 145 checkAvailability(); 146 return newProviderBuilder().setName(providerName).build(); 147 } 148 149 public static class ProviderBuilder { 150 private String name = Platform.getDefaultProviderName(); 151 private boolean provideTrustManager = Platform.provideTrustManagerByDefault(); 152 private String defaultTlsProtocol = NativeCrypto.SUPPORTED_PROTOCOL_TLSV1_3; 153 154 private ProviderBuilder() {} 155 156 /** 157 * Sets the name of the Provider to be built. 158 */ 159 public ProviderBuilder setName(String name) { 160 this.name = name; 161 return this; 162 } 163 164 /** 165 * Causes the returned provider to provide an implementation of 166 * {@link javax.net.ssl.TrustManagerFactory}. 167 * @deprecated Use provideTrustManager(true) 168 */ 169 @Deprecated 170 public ProviderBuilder provideTrustManager() { 171 return provideTrustManager(true); 172 } 173 174 /** 175 * Specifies whether the returned provider will provide an implementation of 176 * {@link javax.net.ssl.TrustManagerFactory}. 177 */ 178 public ProviderBuilder provideTrustManager(boolean provide) { 179 this.provideTrustManager = provide; 180 return this; 181 } 182 183 /** 184 * Specifies what the default TLS protocol should be for SSLContext identifiers 185 * {@code TLS}, {@code SSL}, and {@code Default}. 186 */ 187 public ProviderBuilder defaultTlsProtocol(String defaultTlsProtocol) { 188 this.defaultTlsProtocol = defaultTlsProtocol; 189 return this; 190 } 191 192 public Provider build() { 193 return new OpenSSLProvider(name, provideTrustManager, defaultTlsProtocol); 194 } 195 } 196 197 public static ProviderBuilder newProviderBuilder() { 198 return new ProviderBuilder(); 199 } 200 201 /** 202 * Returns the maximum length (in bytes) of an encrypted packet. 203 */ 204 public static int maxEncryptedPacketLength() { 205 return NativeConstants.SSL3_RT_MAX_PACKET_SIZE; 206 } 207 208 /** 209 * Gets the default X.509 trust manager. 210 */ 211 @ExperimentalApi 212 public static X509TrustManager getDefaultX509TrustManager() throws KeyManagementException { 213 checkAvailability(); 214 return SSLParametersImpl.getDefaultX509TrustManager(); 215 } 216 217 /** 218 * Indicates whether the given {@link SSLContext} was created by this distribution of Conscrypt. 219 */ 220 public static boolean isConscrypt(SSLContext context) { 221 return context.getProvider() instanceof OpenSSLProvider; 222 } 223 224 /** 225 * Constructs a new instance of the preferred {@link SSLContextSpi}. 226 */ 227 public static SSLContextSpi newPreferredSSLContextSpi() { 228 checkAvailability(); 229 return OpenSSLContextImpl.getPreferred(); 230 } 231 232 /** 233 * Sets the client-side persistent cache to be used by the context. 234 */ 235 public static void setClientSessionCache(SSLContext context, SSLClientSessionCache cache) { 236 SSLSessionContext clientContext = context.getClientSessionContext(); 237 if (!(clientContext instanceof ClientSessionContext)) { 238 throw new IllegalArgumentException( 239 "Not a conscrypt client context: " + clientContext.getClass().getName()); 240 } 241 ((ClientSessionContext) clientContext).setPersistentCache(cache); 242 } 243 244 /** 245 * Sets the server-side persistent cache to be used by the context. 246 */ 247 public static void setServerSessionCache(SSLContext context, SSLServerSessionCache cache) { 248 SSLSessionContext serverContext = context.getServerSessionContext(); 249 if (!(serverContext instanceof ServerSessionContext)) { 250 throw new IllegalArgumentException( 251 "Not a conscrypt client context: " + serverContext.getClass().getName()); 252 } 253 ((ServerSessionContext) serverContext).setPersistentCache(cache); 254 } 255 256 /** 257 * Indicates whether the given {@link SSLSocketFactory} was created by this distribution of 258 * Conscrypt. 259 */ 260 public static boolean isConscrypt(SSLSocketFactory factory) { 261 return factory instanceof OpenSSLSocketFactoryImpl; 262 } 263 264 private static OpenSSLSocketFactoryImpl toConscrypt(SSLSocketFactory factory) { 265 if (!isConscrypt(factory)) { 266 throw new IllegalArgumentException( 267 "Not a conscrypt socket factory: " + factory.getClass().getName()); 268 } 269 return (OpenSSLSocketFactoryImpl) factory; 270 } 271 272 /** 273 * Configures the default socket to be created for all socket factory instances. 274 */ 275 @ExperimentalApi 276 public static void setUseEngineSocketByDefault(boolean useEngineSocket) { 277 OpenSSLSocketFactoryImpl.setUseEngineSocketByDefault(useEngineSocket); 278 OpenSSLServerSocketFactoryImpl.setUseEngineSocketByDefault(useEngineSocket); 279 } 280 281 /** 282 * Configures the socket to be created for the given socket factory instance. 283 */ 284 @ExperimentalApi 285 public static void setUseEngineSocket(SSLSocketFactory factory, boolean useEngineSocket) { 286 toConscrypt(factory).setUseEngineSocket(useEngineSocket); 287 } 288 289 /** 290 * Indicates whether the given {@link SSLServerSocketFactory} was created by this distribution 291 * of Conscrypt. 292 */ 293 public static boolean isConscrypt(SSLServerSocketFactory factory) { 294 return factory instanceof OpenSSLServerSocketFactoryImpl; 295 } 296 297 private static OpenSSLServerSocketFactoryImpl toConscrypt(SSLServerSocketFactory factory) { 298 if (!isConscrypt(factory)) { 299 throw new IllegalArgumentException( 300 "Not a conscrypt server socket factory: " + factory.getClass().getName()); 301 } 302 return (OpenSSLServerSocketFactoryImpl) factory; 303 } 304 305 /** 306 * Configures the socket to be created for the given server socket factory instance. 307 */ 308 @ExperimentalApi 309 public static void setUseEngineSocket(SSLServerSocketFactory factory, boolean useEngineSocket) { 310 toConscrypt(factory).setUseEngineSocket(useEngineSocket); 311 } 312 313 /** 314 * Indicates whether the given {@link SSLSocket} was created by this distribution of Conscrypt. 315 */ 316 public static boolean isConscrypt(SSLSocket socket) { 317 return socket instanceof AbstractConscryptSocket; 318 } 319 320 private static AbstractConscryptSocket toConscrypt(SSLSocket socket) { 321 if (!isConscrypt(socket)) { 322 throw new IllegalArgumentException( 323 "Not a conscrypt socket: " + socket.getClass().getName()); 324 } 325 return (AbstractConscryptSocket) socket; 326 } 327 328 /** 329 * This method enables Server Name Indication (SNI) and overrides the hostname supplied 330 * during socket creation. If the hostname is not a valid SNI hostname, the SNI extension 331 * will be omitted from the handshake. 332 * 333 * @param socket the socket 334 * @param hostname the desired SNI hostname, or null to disable 335 */ 336 public static void setHostname(SSLSocket socket, String hostname) { 337 toConscrypt(socket).setHostname(hostname); 338 } 339 340 /** 341 * Returns either the hostname supplied during socket creation or via 342 * {@link #setHostname(SSLSocket, String)}. No DNS resolution is attempted before 343 * returning the hostname. 344 */ 345 public static String getHostname(SSLSocket socket) { 346 return toConscrypt(socket).getHostname(); 347 } 348 349 /** 350 * This method attempts to create a textual representation of the peer host or IP. Does 351 * not perform a reverse DNS lookup. This is typically used during session creation. 352 */ 353 public static String getHostnameOrIP(SSLSocket socket) { 354 return toConscrypt(socket).getHostnameOrIP(); 355 } 356 357 /** 358 * This method enables session ticket support. 359 * 360 * @param socket the socket 361 * @param useSessionTickets True to enable session tickets 362 */ 363 public static void setUseSessionTickets(SSLSocket socket, boolean useSessionTickets) { 364 toConscrypt(socket).setUseSessionTickets(useSessionTickets); 365 } 366 367 /** 368 * Enables/disables TLS Channel ID for the given server-side socket. 369 * 370 * <p>This method needs to be invoked before the handshake starts. 371 * 372 * @param socket the socket 373 * @param enabled Whether to enable channel ID. 374 * @throws IllegalStateException if this is a client socket or if the handshake has already 375 * started. 376 */ 377 public static void setChannelIdEnabled(SSLSocket socket, boolean enabled) { 378 toConscrypt(socket).setChannelIdEnabled(enabled); 379 } 380 381 /** 382 * Gets the TLS Channel ID for the given server-side socket. Channel ID is only available 383 * once the handshake completes. 384 * 385 * @param socket the socket 386 * @return channel ID or {@code null} if not available. 387 * @throws IllegalStateException if this is a client socket or if the handshake has not yet 388 * completed. 389 * @throws SSLException if channel ID is available but could not be obtained. 390 */ 391 public static byte[] getChannelId(SSLSocket socket) throws SSLException { 392 return toConscrypt(socket).getChannelId(); 393 } 394 395 /** 396 * Sets the {@link PrivateKey} to be used for TLS Channel ID by this client socket. 397 * 398 * <p>This method needs to be invoked before the handshake starts. 399 * 400 * @param socket the socket 401 * @param privateKey private key (enables TLS Channel ID) or {@code null} for no key 402 * (disables TLS Channel ID). 403 * The private key must be an Elliptic Curve (EC) key based on the NIST P-256 curve (aka 404 * SECG secp256r1 or ANSI 405 * X9.62 prime256v1). 406 * @throws IllegalStateException if this is a server socket or if the handshake has already 407 * started. 408 */ 409 public static void setChannelIdPrivateKey(SSLSocket socket, PrivateKey privateKey) { 410 toConscrypt(socket).setChannelIdPrivateKey(privateKey); 411 } 412 413 /** 414 * Returns the ALPN protocol agreed upon by client and server. 415 * 416 * @param socket the socket 417 * @return the selected protocol or {@code null} if no protocol was agreed upon. 418 */ 419 public static String getApplicationProtocol(SSLSocket socket) { 420 return toConscrypt(socket).getApplicationProtocol(); 421 } 422 423 /** 424 * Sets an application-provided ALPN protocol selector. If provided, this will override 425 * the list of protocols set by {@link #setApplicationProtocols(SSLSocket, String[])}. 426 * 427 * @param socket the socket 428 * @param selector the ALPN protocol selector 429 */ 430 public static void setApplicationProtocolSelector(SSLSocket socket, 431 ApplicationProtocolSelector selector) { 432 toConscrypt(socket).setApplicationProtocolSelector(selector); 433 } 434 435 /** 436 * Sets the application-layer protocols (ALPN) in prioritization order. 437 * 438 * @param socket the socket being configured 439 * @param protocols the protocols in descending order of preference. If empty, no protocol 440 * indications will be used. This array will be copied. 441 * @throws IllegalArgumentException - if protocols is null, or if any element in a non-empty 442 * array is null or an empty (zero-length) string 443 */ 444 public static void setApplicationProtocols(SSLSocket socket, String[] protocols) { 445 toConscrypt(socket).setApplicationProtocols(protocols); 446 } 447 448 /** 449 * Gets the application-layer protocols (ALPN) in prioritization order. 450 * 451 * @param socket the socket 452 * @return the protocols in descending order of preference, or an empty array if protocol 453 * indications are not being used. Always returns a new array. 454 */ 455 public static String[] getApplicationProtocols(SSLSocket socket) { 456 return toConscrypt(socket).getApplicationProtocols(); 457 } 458 459 /** 460 * Returns the tls-unique channel binding value for this connection, per RFC 5929. This 461 * will return {@code null} if there is no such value available, such as if the handshake 462 * has not yet completed or this connection is closed. 463 */ 464 public static byte[] getTlsUnique(SSLSocket socket) { 465 return toConscrypt(socket).getTlsUnique(); 466 } 467 468 /** 469 * Exports a value derived from the TLS master secret as described in RFC 5705. 470 * 471 * @param label the label to use in calculating the exported value. This must be 472 * an ASCII-only string. 473 * @param context the application-specific context value to use in calculating the 474 * exported value. This may be {@code null} to use no application context, which is 475 * treated differently than an empty byte array. 476 * @param length the number of bytes of keying material to return. 477 * @return a value of the specified length, or {@code null} if the handshake has not yet 478 * completed or the connection has been closed. 479 * @throws SSLException if the value could not be exported. 480 */ 481 public static byte[] exportKeyingMaterial(SSLSocket socket, String label, byte[] context, 482 int length) throws SSLException { 483 return toConscrypt(socket).exportKeyingMaterial(label, context, length); 484 } 485 486 /** 487 * Indicates whether the given {@link SSLEngine} was created by this distribution of Conscrypt. 488 */ 489 public static boolean isConscrypt(SSLEngine engine) { 490 return engine instanceof AbstractConscryptEngine; 491 } 492 493 private static AbstractConscryptEngine toConscrypt(SSLEngine engine) { 494 if (!isConscrypt(engine)) { 495 throw new IllegalArgumentException( 496 "Not a conscrypt engine: " + engine.getClass().getName()); 497 } 498 return (AbstractConscryptEngine) engine; 499 } 500 501 /** 502 * Provides the given engine with the provided bufferAllocator. 503 * @throws IllegalArgumentException if the provided engine is not a Conscrypt engine. 504 * @throws IllegalStateException if the provided engine has already begun its handshake. 505 */ 506 @ExperimentalApi 507 public static void setBufferAllocator(SSLEngine engine, BufferAllocator bufferAllocator) { 508 toConscrypt(engine).setBufferAllocator(bufferAllocator); 509 } 510 511 /** 512 * Provides the given socket with the provided bufferAllocator. If the given socket is a 513 * Conscrypt socket but does not use buffer allocators, this method does nothing. 514 * @throws IllegalArgumentException if the provided socket is not a Conscrypt socket. 515 * @throws IllegalStateException if the provided socket has already begun its handshake. 516 */ 517 @ExperimentalApi 518 public static void setBufferAllocator(SSLSocket socket, BufferAllocator bufferAllocator) { 519 AbstractConscryptSocket s = toConscrypt(socket); 520 if (s instanceof ConscryptEngineSocket) { 521 ((ConscryptEngineSocket) s).setBufferAllocator(bufferAllocator); 522 } 523 } 524 525 /** 526 * Configures the default {@link BufferAllocator} to be used by all future 527 * {@link SSLEngine} instances from this provider. 528 */ 529 @ExperimentalApi 530 public static void setDefaultBufferAllocator(BufferAllocator bufferAllocator) { 531 ConscryptEngine.setDefaultBufferAllocator(bufferAllocator); 532 } 533 534 /** 535 * This method enables Server Name Indication (SNI) and overrides the hostname supplied 536 * during engine creation. 537 * 538 * @param engine the engine 539 * @param hostname the desired SNI hostname, or {@code null} to disable 540 */ 541 public static void setHostname(SSLEngine engine, String hostname) { 542 toConscrypt(engine).setHostname(hostname); 543 } 544 545 /** 546 * Returns either the hostname supplied during socket creation or via 547 * {@link #setHostname(SSLEngine, String)}. No DNS resolution is attempted before 548 * returning the hostname. 549 */ 550 public static String getHostname(SSLEngine engine) { 551 return toConscrypt(engine).getHostname(); 552 } 553 554 /** 555 * Returns the maximum overhead, in bytes, of sealing a record with SSL. 556 */ 557 public static int maxSealOverhead(SSLEngine engine) { 558 return toConscrypt(engine).maxSealOverhead(); 559 } 560 561 /** 562 * Sets a listener on the given engine for completion of the TLS handshake 563 */ 564 public static void setHandshakeListener(SSLEngine engine, HandshakeListener handshakeListener) { 565 toConscrypt(engine).setHandshakeListener(handshakeListener); 566 } 567 568 /** 569 * Enables/disables TLS Channel ID for the given server-side engine. 570 * 571 * <p>This method needs to be invoked before the handshake starts. 572 * 573 * @param engine the engine 574 * @param enabled Whether to enable channel ID. 575 * @throws IllegalStateException if this is a client engine or if the handshake has already 576 * started. 577 */ 578 public static void setChannelIdEnabled(SSLEngine engine, boolean enabled) { 579 toConscrypt(engine).setChannelIdEnabled(enabled); 580 } 581 582 /** 583 * Gets the TLS Channel ID for the given server-side engine. Channel ID is only available 584 * once the handshake completes. 585 * 586 * @param engine the engine 587 * @return channel ID or {@code null} if not available. 588 * @throws IllegalStateException if this is a client engine or if the handshake has not yet 589 * completed. 590 * @throws SSLException if channel ID is available but could not be obtained. 591 */ 592 public static byte[] getChannelId(SSLEngine engine) throws SSLException { 593 return toConscrypt(engine).getChannelId(); 594 } 595 596 /** 597 * Sets the {@link PrivateKey} to be used for TLS Channel ID by this client engine. 598 * 599 * <p>This method needs to be invoked before the handshake starts. 600 * 601 * @param engine the engine 602 * @param privateKey private key (enables TLS Channel ID) or {@code null} for no key 603 * (disables TLS Channel ID). 604 * The private key must be an Elliptic Curve (EC) key based on the NIST P-256 curve (aka 605 * SECG secp256r1 or ANSI X9.62 prime256v1). 606 * @throws IllegalStateException if this is a server engine or if the handshake has already 607 * started. 608 */ 609 public static void setChannelIdPrivateKey(SSLEngine engine, PrivateKey privateKey) { 610 toConscrypt(engine).setChannelIdPrivateKey(privateKey); 611 } 612 613 /** 614 * Extended unwrap method for multiple source and destination buffers. 615 * 616 * @param engine the target engine for the unwrap 617 * @param srcs the source buffers 618 * @param dsts the destination buffers 619 * @return the result of the unwrap operation 620 * @throws SSLException thrown if an SSL error occurred 621 */ 622 public static SSLEngineResult unwrap(SSLEngine engine, final ByteBuffer[] srcs, 623 final ByteBuffer[] dsts) throws SSLException { 624 return toConscrypt(engine).unwrap(srcs, dsts); 625 } 626 627 /** 628 * Exteneded unwrap method for multiple source and destination buffers. 629 * 630 * @param engine the target engine for the unwrap. 631 * @param srcs the source buffers 632 * @param srcsOffset the offset in the {@code srcs} array of the first source buffer 633 * @param srcsLength the number of source buffers starting at {@code srcsOffset} 634 * @param dsts the destination buffers 635 * @param dstsOffset the offset in the {@code dsts} array of the first destination buffer 636 * @param dstsLength the number of destination buffers starting at {@code dstsOffset} 637 * @return the result of the unwrap operation 638 * @throws SSLException thrown if an SSL error occurred 639 */ 640 public static SSLEngineResult unwrap(SSLEngine engine, final ByteBuffer[] srcs, int srcsOffset, 641 final int srcsLength, final ByteBuffer[] dsts, final int dstsOffset, 642 final int dstsLength) throws SSLException { 643 return toConscrypt(engine).unwrap( 644 srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength); 645 } 646 647 /** 648 * This method enables session ticket support. 649 * 650 * @param engine the engine 651 * @param useSessionTickets True to enable session tickets 652 */ 653 public static void setUseSessionTickets(SSLEngine engine, boolean useSessionTickets) { 654 toConscrypt(engine).setUseSessionTickets(useSessionTickets); 655 } 656 657 /** 658 * Sets the application-layer protocols (ALPN) in prioritization order. 659 * 660 * @param engine the engine being configured 661 * @param protocols the protocols in descending order of preference. If empty, no protocol 662 * indications will be used. This array will be copied. 663 * @throws IllegalArgumentException - if protocols is null, or if any element in a non-empty 664 * array is null or an empty (zero-length) string 665 */ 666 public static void setApplicationProtocols(SSLEngine engine, String[] protocols) { 667 toConscrypt(engine).setApplicationProtocols(protocols); 668 } 669 670 /** 671 * Gets the application-layer protocols (ALPN) in prioritization order. 672 * 673 * @param engine the engine 674 * @return the protocols in descending order of preference, or an empty array if protocol 675 * indications are not being used. Always returns a new array. 676 */ 677 public static String[] getApplicationProtocols(SSLEngine engine) { 678 return toConscrypt(engine).getApplicationProtocols(); 679 } 680 681 /** 682 * Sets an application-provided ALPN protocol selector. If provided, this will override 683 * the list of protocols set by {@link #setApplicationProtocols(SSLEngine, String[])}. 684 * 685 * @param engine the engine 686 * @param selector the ALPN protocol selector 687 */ 688 public static void setApplicationProtocolSelector(SSLEngine engine, 689 ApplicationProtocolSelector selector) { 690 toConscrypt(engine).setApplicationProtocolSelector(selector); 691 } 692 693 /** 694 * Returns the ALPN protocol agreed upon by client and server. 695 * 696 * @param engine the engine 697 * @return the selected protocol or {@code null} if no protocol was agreed upon. 698 */ 699 public static String getApplicationProtocol(SSLEngine engine) { 700 return toConscrypt(engine).getApplicationProtocol(); 701 } 702 703 /** 704 * Returns the tls-unique channel binding value for this connection, per RFC 5929. This 705 * will return {@code null} if there is no such value available, such as if the handshake 706 * has not yet completed or this connection is closed. 707 */ 708 public static byte[] getTlsUnique(SSLEngine engine) { 709 return toConscrypt(engine).getTlsUnique(); 710 } 711 712 /** 713 * Exports a value derived from the TLS master secret as described in RFC 5705. 714 * 715 * @param label the label to use in calculating the exported value. This must be 716 * an ASCII-only string. 717 * @param context the application-specific context value to use in calculating the 718 * exported value. This may be {@code null} to use no application context, which is 719 * treated differently than an empty byte array. 720 * @param length the number of bytes of keying material to return. 721 * @return a value of the specified length, or {@code null} if the handshake has not yet 722 * completed or the connection has been closed. 723 * @throws SSLException if the value could not be exported. 724 */ 725 public static byte[] exportKeyingMaterial(SSLEngine engine, String label, byte[] context, 726 int length) throws SSLException { 727 return toConscrypt(engine).exportKeyingMaterial(label, context, length); 728 } 729 730 /** 731 * Indicates whether the given {@link TrustManager} was created by this distribution of 732 * Conscrypt. 733 */ 734 public static boolean isConscrypt(TrustManager trustManager) { 735 return trustManager instanceof TrustManagerImpl; 736 } 737 738 private static TrustManagerImpl toConscrypt(TrustManager trustManager) { 739 if (!isConscrypt(trustManager)) { 740 throw new IllegalArgumentException( 741 "Not a Conscrypt trust manager: " + trustManager.getClass().getName()); 742 } 743 return (TrustManagerImpl) trustManager; 744 } 745 746 /** 747 * Set the default hostname verifier that will be used for HTTPS endpoint identification by 748 * Conscrypt trust managers. If {@code null} (the default), endpoint identification will use 749 * the default hostname verifier set in 750 * {@link HttpsURLConnection#setDefaultHostnameVerifier(javax.net.ssl.HostnameVerifier)}. 751 */ 752 public synchronized static void setDefaultHostnameVerifier(ConscryptHostnameVerifier verifier) { 753 TrustManagerImpl.setDefaultHostnameVerifier(verifier); 754 } 755 756 /** 757 * Returns the currently-set default hostname verifier for Conscrypt trust managers. 758 * 759 * @see #setDefaultHostnameVerifier(ConscryptHostnameVerifier) 760 */ 761 public synchronized static ConscryptHostnameVerifier getDefaultHostnameVerifier(TrustManager trustManager) { 762 return TrustManagerImpl.getDefaultHostnameVerifier(); 763 } 764 765 /** 766 * Set the hostname verifier that will be used for HTTPS endpoint identification by the 767 * given trust manager. If {@code null} (the default), endpoint identification will use the 768 * default hostname verifier set in {@link #setDefaultHostnameVerifier(ConscryptHostnameVerifier)}. 769 * 770 * @throws IllegalArgumentException if the provided trust manager is not a Conscrypt trust 771 * manager per {@link #isConscrypt(TrustManager)} 772 */ 773 public static void setHostnameVerifier(TrustManager trustManager, ConscryptHostnameVerifier verifier) { 774 toConscrypt(trustManager).setHostnameVerifier(verifier); 775 } 776 777 /** 778 * Returns the currently-set hostname verifier for the given trust manager. 779 * 780 * @throws IllegalArgumentException if the provided trust manager is not a Conscrypt trust 781 * manager per {@link #isConscrypt(TrustManager)} 782 * 783 * @see #setHostnameVerifier(TrustManager, ConscryptHostnameVerifier) 784 */ 785 public static ConscryptHostnameVerifier getHostnameVerifier(TrustManager trustManager) { 786 return toConscrypt(trustManager).getHostnameVerifier(); 787 } 788 789 /** 790 * Wraps the HttpsURLConnection.HostnameVerifier into a ConscryptHostnameVerifier 791 */ 792 public static ConscryptHostnameVerifier wrapHostnameVerifier(final HostnameVerifier verifier) { 793 return new ConscryptHostnameVerifier() { 794 @Override 795 public boolean verify(X509Certificate[] certificates, String hostname, SSLSession session) { 796 return verifier.verify(hostname, session); 797 } 798 }; 799 } 800}