/
githubmirror
/
galahad
Обзор
Документация
Войти
/
githubmirror
/
galahad
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/java.base/share/classes/jdk/internal/net/quic/QuicTLSContext.java
151 строка
6 KB
Daniel Jeliński
8371887: HttpClient: SSLParameters with no protocols configured disable HTTP2+ support
27 ноя 2025, 12:27
27 ноя 2025, 12:27
1f417e7
Код
Авторство
О чём код?
/* * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package jdk.internal.net.quic; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.Arrays; import java.util.Objects; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContextSpi; import javax.net.ssl.SSLParameters; import sun.security.ssl.QuicTLSEngineImpl; import sun.security.ssl.SSLContextImpl; /** * Instances of this class act as a factory for creation * of {@link QuicTLSEngine QUIC TLS engine}. */ public final class QuicTLSContext { // In this implementation, we have a dependency on // sun.security.ssl.SSLContextImpl. We can only support // Quic on SSLContext instances created by the default // SunJSSE Provider private final SSLContextImpl sslCtxImpl; /** * {@return {@code true} if the given {@code sslContext} supports QUIC TLS, {@code false} otherwise} * @param sslContext an {@link SSLContext} */ public static boolean isQuicCompatible(final SSLContext sslContext) { boolean parametersSupported = isQuicCompatible(sslContext.getSupportedSSLParameters()); if (!parametersSupported) { return false; } // horrible hack - what we do here is try and get hold of a SSLContext // that has already been initialised and configured with the HttpClient. // We see if that SSLContext is created using an implementation of // sun.security.ssl.SSLContextImpl. Since there's no API // available to get hold of that underlying implementation, we use // MethodHandle lookup to get access to the field which holds that // detail. final Object underlyingImpl = CONTEXT_SPI.get(sslContext); if (!(underlyingImpl instanceof SSLContextImpl ssci)) { return false; } return ssci.isUsableWithQuic(); } /** * {@return {@code true} if protocols of the given {@code parameters} support QUIC TLS, {@code false} otherwise} */ private static boolean isQuicCompatible(SSLParameters parameters) { String[] protocols = parameters.getProtocols(); return protocols != null && Arrays.asList(protocols).contains("TLSv1.3"); } private static SSLContextImpl getSSLContextImpl( final SSLContext sslContext) { final Object underlyingImpl = CONTEXT_SPI.get(sslContext); assert underlyingImpl instanceof SSLContextImpl; return (SSLContextImpl) underlyingImpl; } /** * Constructs a QuicTLSContext for the given {@code sslContext} * * @param sslContext The SSLContext * @throws IllegalArgumentException If the passed {@code sslContext} isn't * supported by the QuicTLSContext * @see #isQuicCompatible(SSLContext) */ public QuicTLSContext(final SSLContext sslContext) { Objects.requireNonNull(sslContext); if (!isQuicCompatible(sslContext)) { throw new IllegalArgumentException( "Cannot construct a QUIC TLS context with the given SSLContext"); } this.sslCtxImpl = getSSLContextImpl(sslContext); } /** * Creates a {@link QuicTLSEngine} using this context * <p> * This method does not provide hints for session caching. * * @return the newly created QuicTLSEngine */ public QuicTLSEngine createEngine() { return createEngine(null, -1); } /** * Creates a {@link QuicTLSEngine} using this context using * advisory peer information. * <p> * The provided parameters will be used as hints for session caching. * The {@code peerHost} parameter will be used in the server_name extension, * unless overridden later. * * @param peerHost The peer hostname or IP address. Can be null. * @param peerPort The peer port, can be -1 if the port is unknown * @return the newly created QuicTLSEngine */ public QuicTLSEngine createEngine(final String peerHost, final int peerPort) { return new QuicTLSEngineImpl(this.sslCtxImpl, peerHost, peerPort); } // This VarHandle is used to access the SSLContext::contextSpi // field which is not publicly accessible. // In this implementation, Quic is only supported for SSLContext // instances whose underlying implementation is provided by a // sun.security.ssl.SSLContextImpl private static final VarHandle CONTEXT_SPI; static { try { final MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(SSLContext.class, MethodHandles.lookup()); final VarHandle vh = lookup.findVarHandle(SSLContext.class, "contextSpi", SSLContextSpi.class); CONTEXT_SPI = vh; } catch (Exception x) { throw new ExceptionInInitializerError(x); } } }