使用下划线“_”作为 SNI 服务器名称的一部分的 JVM 崩溃

JVM crashes using underline '_' as part of SNI server name

我正在为我的应用程序框架使用 Netty 4.1.14.Final。我想实现当客户端使用 netty-tcnative-boringssl-static.

请求时,服务器可以检查 SNI 信息

但是当我将 -servername 指定为 svc.v1 时,我的应用程序崩溃了一次,我收到了这条消息:

java: ../ssl/handshake_server.c:541: negotiate_version: Assertion `!ssl->s3->have_version' failed.

使用 OpenSSL 命令:

openssl s_client -cert service.crt -key service.key -CAfile root_ca.pem -connect 127.0.0.1:8080 -servername svc.v1_1
CONNECTED(00000003)
write:errno=0
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 210 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : 0000
    Session-ID:
    Session-ID-ctx:
    Master-Key:
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1532336403
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
---

但是,如果我将 -servername 指定为 svc.v1,并且不带下划线 _

,效果会很好 这是我的 Netty 服务器实现:
// define ssl provider
private static final SslProvider SSL_PROVIDER = SslProvider.OPENSSL;

// factory method for creating ssl context
public SslContext serverCtx(InputStream certificate, InputStream privateKey) {
        try {
            return SslContextBuilder.forServer(certificate, privateKey)
                                    .sslProvider(SSL_PROVIDER)                                         
                                    .clientAuth(ClientAuth.REQUIRE)
                               .trustManager(TwoWayTrustManagerFactory.INSTANCE)
                                    .build();
        } catch (Exception e) {
            throw new RuntimeException("failed to create ssl context", e);
        }
}

// SNI Matcher implementation
@Slf4j
public class MySNIMatcher extends SNIMatcher {

    private final byte[] hostIdentifier;

    public MySNIMatcher(Identifier hostIdentifier) {
        super(0);
        this.hostIdentifier = hostIdentifier.idDistKey().getBytes(StandardCharsets.US_ASCII);
    }

    @Override
    public boolean matches(SNIServerName sniServerName) {
        return Arrays.equals(sniServerName.getEncoded(), hostIdentifier);
    }
}

// Netty bootstrap
bootstrap.childHandler(new ChannelInitializer<Channel>() {
    @Override
    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        if (conf.logEnable())
            pipeline.addLast("logging", new LoggingHandler());

        if (conf.sslEnable()) {
            // conf.sslCtx() will actually use serverCtx() to create context
            SSLEngine engine = conf.sslCtx().newEngine(ch.alloc());
            SSLParameters s = engine.getSSLParameters();
            s.setSNIMatchers(new MySNIMatcher(...));
            s.setEndpointIdentificationAlgorithm("HTTPS");
            engine.setSSLParameters(s);
            pipeline.addLast("ssl", new SslHandler(engine, true));
        }

        codec(pipeline);

        int idleTimeout = (int) TimeUnit.MILLISECONDS.toSeconds(conf.idleTimeout());
        if (0 < idleTimeout)
            pipeline.addLast("idle", new IdleStateHandler(0, 0, idleTimeout));

        pipeline.addLast("handler", handler);
    }                  
})

版本: 网络 -> 4.1.14.Final netty-tcnative-boringssl-static -> 2.0.5.Final

根据原始 RFC 952 和 RFC 1123 修改,主机名不允许包含下划线字符。以下内容来自 Hostname.

的 Wikipedia 页面

The Internet standards (Requests for Comments) for protocols mandate that component hostname labels may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner), the digits '0' through '9', and the minus sign ('-'). The original specification of hostnames in RFC 952, mandated that labels could not start with a digit or with a minus sign, and must not end with a minus sign. However, a subsequent specification (RFC 1123) permitted hostname labels to start with digits. No other symbols, punctuation characters, or white space are permitted.