最后,解决了这个问题。看起来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()的所有调用也都成功。
我想发布这个,因为这似乎有很多问题。
我建议使用'-Djavax.net.debug = ssl'或至少'Djavax.net.debug = ssl:handshake'来调试握手以查看您是否获得'CertificateRequest'并检查'certificate_authorities'列表它包含。 – Bruno 2012-03-10 15:31:38