RpcStreamConnection extends RpcConnection { private void initSSL() throws ConnectionException { if (nonNull(socket)) { try { SSLSession sslSession = ((SSLSocket) socket).getSession(); throwConnectionExceptionIfConditionFails(sslSession.isValid(), "Error occurred during the SSL handshake: invalid SSL session"); Certificate[] serverCerts = sslSession.getPeerCertificates(); throwConnectionExceptionIfConditionFails( nonNull(serverCerts) && (serverCerts.length != 0) && nonNull(serverCerts[0]), "Error occurred during the SSL handshake: no certificate retrieved from SSL session"); ((X509Certificate) serverCerts[0]).checkValidity(); PublicKey serverPubKey = serverCerts[0].getPublicKey(); throwConnectionExceptionIfConditionFails(nonNull(serverPubKey), "Error occurred during the SSL handshake: no public key retrieved from server certificate"); fingerprint = ClientTrust.generateFingerprint(serverPubKey); } catch (CertificateExpiredException e) { throwConnectionException(e, "Error occurred during the SSL handshake: certificate expired:"); } catch (CertificateNotYetValidException e) { throwConnectionException(e, "Error occurred during the SSL handshake: certificate not yet valid"); } catch (NoSuchAlgorithmException e) { throwConnectionException(e, "Error occurred while generating the fingerprint for the Perforce SSL connection"); } catch (IOException e) { String errorMessage = format( "Error occurred during SSL hankshake. Please check the release notes for known SSL issues"); Log.error(errorMessage); Log.exception(e); throwConnectionException(e, errorMessage); } } } RpcStreamConnection(String serverHost, int serverPort, Properties props,
            ServerStats stats, Charset charset);  RpcStreamConnection(String serverHost, int serverPort, Properties props,
            ServerStats stats, Charset charset, boolean secure);  RpcStreamConnection(String serverHost, int serverPort, Properties props,
            ServerStats stats, Charset charset, Socket socket);  RpcStreamConnection(String serverHost, int serverPort, Properties props,
            ServerStats stats, Charset charset, RpcSocketPool pool);  RpcStreamConnection(String serverHost, int serverPort, Properties props,
            ServerStats stats, Charset charset, Socket socket, boolean secure);  RpcStreamConnection(String serverHost, int serverPort, Properties props,
            ServerStats stats, Charset charset, RpcSocketPool pool, boolean secure);  RpcStreamConnection(String serverHost, int serverPort, Properties props,
            ServerStats stats, Charset charset, Socket socket, RpcSocketPool pool, boolean secure);  RpcStreamConnection(String serverHost, int serverPort, Properties props,
            ServerStats stats, Charset charset, Socket socket, RpcSocketPool pool, boolean secure,
            String rsh); String getServerIpPort(); String getClientIpPort(); void disconnect(final RpcPacketDispatcher dispatcher); RpcPacket getRpcPacket(); RpcPacket getRpcPacket(final RpcPacketFieldRule fieldRule,
            final IFilterCallback filterCallback); int getSystemRecvBufferSize(); int getSystemSendBufferSize(); long putRpcPackets(@Nonnull RpcPacket[] packets); long putRpcPacket(@Nonnull RpcPacket packet); @Override void useConnectionCompression(); static final String TRACE_PREFIX; }
@Test public void initSSL() throws InvocationTargetException, IllegalAccessException, SSLPeerUnverifiedException, CertificateNotYetValidException, CertificateExpiredException { Method initSSL = getPrivateMethod(RpcStreamConnection.class, "initSSL"); PublicKey serverPubKey = mock(PublicKey.class); when(serverPubKey.getEncoded()).thenReturn(new byte[] { 'a', 'b', 'c' }); X509Certificate certificate = mock(X509Certificate.class); when(certificate.getPublicKey()).thenReturn(serverPubKey); doNothing().when(certificate).checkValidity(); SSLSession sslSession = mock(SSLSession.class); when(sslSession.isValid()).thenReturn(true); Certificate[] serverCerts = new Certificate[] { certificate }; when(sslSession.getPeerCertificates()).thenReturn(serverCerts); SSLSocket sslSocket = mock(SSLSocket.class); when(sslSocket.getSession()).thenReturn(sslSession); mockConnection.socket(sslSocket); initSSL.invoke(mockConnection); reset(sslSession); when(sslSession.isValid()).thenReturn(true); expectThrows(InvocationTargetException.class, () -> initSSL.invoke(mockConnection)); reset(sslSession); when(sslSession.isValid()).thenReturn(true); when(sslSession.getPeerCertificates()).thenReturn(null); expectThrows(InvocationTargetException.class, () -> initSSL.invoke(mockConnection)); reset(sslSession); when(sslSession.isValid()).thenReturn(true); when(sslSession.getPeerCertificates()).thenReturn(serverCerts); reset(certificate); doNothing().when(certificate).checkValidity(); when(certificate.getPublicKey()).thenReturn(null); expectThrows(InvocationTargetException.class, () -> initSSL.invoke(mockConnection)); reset(sslSession); when(sslSession.isValid()).thenReturn(true); when(sslSession.getPeerCertificates()).thenReturn(serverCerts); reset(certificate); doThrow(CertificateExpiredException.class).when(certificate).checkValidity(); expectThrows(InvocationTargetException.class, () -> initSSL.invoke(mockConnection)); }