终于解决了问题。看来 VMware 走的是一条截然不同的道路。这个问题被误解了。
首先,我使用 WireShark 跟踪连接,服务器在任何时候都不会询问(需要或想要)证书。但是,VirtualCenter (VC) 确实提供了一种方法来注册证书作为连接的一部分,然后使用该证书进行身份验证。为此,它们提供了一种隧道连接方式。
我使用的顺序是:
首先将要连接的 URL 指定为 https://:(注意协议是安全的,但端口不是)。
初始套接字将打开到明文端口。但是将 https 作为协议将强制调用我自己的 SSLSocketFactory。在我的套接字工厂中,我收到了对 public Socket createSocket(Socket s, String host, int port, boolean autoClose) 方法的调用,该方法允许我根据自己的喜好将套接字转换为 SSLSocket。
我的代码基本上看起来像:
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose)
throws IOException {
s.setKeepAlive(true);
String connectReq = "CONNECT /sdkTunnel HTTP/1.1\r\n\r\n";
OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());
writer.write(connectReq, 0, connectReq.length());
writer.flush();
// In this initial response, all that matters is the http code. If
// it is 200, the rest can be ignored.
READ_AND_VERIFY_INITIAL_RESPONSE();
SSLSocket sock = (SSLSocket) origSslSockFactory
.createSocket(s, s.getInetAddress().getHostName(), s.getPort(), true);
// Depending on whether the caller actually does the handshake
// or not, you may need to call handshake here. In my case, I
// did not need to, since HTTPClient I am using calls the
// handshake. Axis does not call, so you may have to in that
// case.
// sock.startHandshake();
return sock;
}
在上面的代码块中,origSslSockFactory 是被你的实现替换的 SSLSocketFactory。在我的例子中,它是 sun.security.ssl.SSLSocketFactoryImpl 的一个实例。
在该过程之后,调用 ExtensionManager.setExtensionCertificate() 成功。随后,对 SessionManager.loginExtensionByCertificate() 的所有调用也成功。
我想发布这个,因为似乎有很多关于这个的问题。