WebSocket over SSL in embedded Jetty 9 - ssl

For this question I have prepared a test project WssEmbedded, which listens for incoming WebSocket connections at localhost:8080 and localhost:8443.
In the MyHandler class I create 2 connectors for this purpose:
public class MyHandler extends WebSocketHandler {
#Override
public void configure(WebSocketServletFactory factory) {
factory.register(MyListener.class);
}
public static void main(String[] args) throws Exception {
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath("keystore.jks");
sslContextFactory.setKeyStorePassword("OBF:1l1a1s3g1yf41xtv20731xtn1yf21s3m1kxs");
Server server = new Server();
server.setHandler(new MyHandler());
ServerConnector wsConnector = new ServerConnector(server);
wsConnector.setHost("127.0.0.1");
wsConnector.setPort(8080);
server.addConnector(wsConnector);
ServerConnector wssConnector = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()));
wssConnector.setHost("127.0.0.1");
wssConnector.setPort(8443);
server.addConnector(wssConnector);
server.start();
server.join();
}
}
I have added a key/certificate pair to keystore.jks with:
keytool -genkey -alias key1 -keyalg RSA -keypass password1 -keystore keystore.jks -storepass password1
The server starts without problems:
2016-06-22 13:34:45.254:INFO::main: Logging initialized #641ms
2016-06-22 13:34:45.404:INFO:oejs.Server:main: jetty-9.3.9.v20160517
2016-06-22 13:34:45.544:INFO:oejs.AbstractConnector:main: Started ServerConnector#3b354e17{HTTP/1.1,[http/1.1]}{127.0.0.1:8080}
2016-06-22 13:34:45.594:INFO:oejus.SslContextFactory:main: x509=X509#64d2d351(key1,h=[],w=[]) for SslContextFactory#1b68b9a4(file:///C:/Users/user1/jetty-newbie/WssEmbedded/keystore.jks,null)
2016-06-22 13:34:46.084:INFO:oejs.AbstractConnector:main: Started ServerConnector#1e53a15{SSL,[ssl]}{127.0.0.1:8443}
2016-06-22 13:34:46.084:INFO:oejs.Server:main: Started #1476ms
Then I have prepared a simple WssClient project for testing the above server:
public static void main(String[] args) {
final String WS_URL = "ws://127.0.0.1:8080";
MyListener socket = new MyListener("Hello world");
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setTrustAll(true);
WebSocketClient client = new WebSocketClient(sslContextFactory);
try {
client.start();
URI uri = new URI(WS_URL);
ClientUpgradeRequest cur = new ClientUpgradeRequest();
client.connect(socket, uri, cur);
socket.awaitClose(5, TimeUnit.SECONDS);
} catch (Throwable t) {
t.printStackTrace();
} finally {
try {
client.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The client works well and prints:
2016-06-22 13:36:06.130:INFO::main: Logging initialized #205ms
onWebSocketConnect: /127.0.0.1:8080
REQUEST:
Hello world
RESPONSE:
Hello /127.0.0.1:58518
onWebSocketClose: 1000 null
The server works well and prints:
2016-06-22 13:35:54.057:INFO:daw.MyListener:qtp1597462040-19: onWebSocketConnect: /127.0.0.1:58511
2016-06-22 13:35:54.097:INFO:daw.MyListener:qtp1597462040-14: onWebSocketText: Hello world
2016-06-22 13:35:54.107:INFO:daw.MyListener:qtp1597462040-13: onWebSocketClose: 1000 - null
However, when I change to WS_URL = "wss://127.0.0.1:8443" then it fails with:
2016-06-22 13:36:29.063:INFO::main: Logging initialized #208ms
onWebSocketError: java.nio.channels.ClosedChannelException
What have I missed here please? How to debug this?
UPDATE:
Thinking that the problem could be the self-signed certificate used above, I have taken a Thawte certificate valid for 3 years for my web domains slova.de and www.slova.de (they point to different IP addresses!) and imported it on CentOS 7 Linux into keystore using Oracle jdk1.8.0_91-1.8.0_91-fcs.x86_64:
# keytool -importcert -file /etc/pki/tls/certs/slova.de.crt -keystore keystore.jks -storepass password1
Owner: CN=slova.de
Issuer: CN=thawte DV SSL SHA256 CA, OU=Domain Validated SSL, O="thawte, Inc.", C=US
Serial number: 9354a665699cafbfa7875490d5a9894
Valid from: Mon Apr 04 02:00:00 CEST 2016 until: Fri Apr 05 01:59:59 CEST 2019
Certificate fingerprints:
MD5: 33:BB:62:8A:09:24:11:0F:C9:40:AA:68:F4:CD:2A:B7
SHA1: 52:E2:B6:79:55:F4:FE:05:0D:2E:7C:18:78:58:22:16:ED:28:4F:B6
SHA256: A3:D3:83:4E:99:01:BF:AE:FB:EB:59:40:23:74:1D:28:93:4B:20:15:1D:E1:AC:1A:97:31:C6:0C:9B:E1:2D:03
Signature algorithm name: SHA256withRSA
Version: 3
As you can see, I have now a trusted certificate there:
# keytool -list -keystore keystore.jks -storepass password1
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 2 entries
key1, Jun 22, 2016, PrivateKeyEntry,
Certificate fingerprint (SHA1): 8F:7D:8E:E0:8F:9E:39:A1:0C:23:D3:FF:4B:47:F5:0D:BA:EC:EE:F3
mykey, Jun 22, 2016, trustedCertEntry,
Certificate fingerprint (SHA1): 52:E2:B6:79:55:F4:FE:05:0D:2E:7C:18:78:58:22:16:ED:28:4F:B6
Then I have started the WssEmbedded program at the www.slova.de:8443 (at my Linux server it is different IP address from slova.de on which Apache is running):
# java -classpath $CPATHS de.afarber.wssembedded.MyHandler 144.76.184.154:8443
2016-06-22 19:45:21.093:INFO::main: Logging initialized #73ms
2016-06-22 19:45:21.144:INFO:oejs.Server:main: jetty-9.3.9.v20160517
2016-06-22 19:45:21.167:INFO:oejs.AbstractConnector:main: Started ServerConnector#6a38e57f{HTTP/1.1,[http/1.1]}{www.slova.de:8080}
2016-06-22 19:45:21.188:INFO:oejus.SslContextFactory:main: x509=X509#7a46a697(key1,h=[],w=[]) for SslContextFactory#5f205aa(file:///usr/share/java/words/keystore.jks,null)
2016-06-22 19:45:21.189:INFO:oejus.SslContextFactory:main: x509=X509#6d86b085(mykey,h=[slova.de, www.slova.de],w=[]) for SslContextFactory#5f205aa(file:///usr/share/java/words/keystore.jks,null)
2016-06-22 19:45:21.327:INFO:oejs.AbstractConnector:main: Started ServerConnector#71bbf57e{SSL,[ssl]}{www.slova.de:8443}
2016-06-22 19:45:21.327:INFO:oejs.Server:main: Started #309ms
And then I have run WssClient against wss://www.slova.de:8443 in NetBeans at my Macbook:
Executing command line: /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java -Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=56634 -classpath /Users/afarber/src/jetty-newbie/WssClient/target/classes:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-client/9.3.9.v20160517/websocket-client-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-util/9.3.9.v20160517/jetty-util-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-io/9.3.9.v20160517/jetty-io-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-common/9.3.9.v20160517/websocket-common-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-api/9.3.9.v20160517/websocket-api-9.3.9.v20160517.jar de.afarber.wssclient.Main
2016-06-22 19:45:31.718:INFO::main: Logging initialized #325ms
onWebSocketError: java.nio.channels.ClosedChannelException
(Nothing changed at the WssEmbedded server output).
Please help, how to get WSS working with embedded Jetty 9?

After adding -Dorg.eclipse.jetty.LEVEL=DEBUG -Djavax.net.debug=ssl friendly folks at the Jetty mailing list have pointed out, that there were NPEs at the server side caused by missing HttpConnectionFactory.
I have missed to copy that part from the embedded/LikeJettyXML example.
The following code in wssembedded/MyHandler.java works better:
public static void main(String[] args) throws Exception {
Server server = new Server();
server.setHandler(new MyHandler());
HttpConfiguration http_config = new HttpConfiguration();
http_config.setSecureScheme("https");
http_config.setSecurePort(8443);
HttpConfiguration https_config = new HttpConfiguration(http_config);
https_config.addCustomizer(new SecureRequestCustomizer());
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath("keystore.jks");
sslContextFactory.setKeyStorePassword("OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0");
ServerConnector wsConnector = new ServerConnector(server);
wsConnector.setHost("localhost");
wsConnector.setPort(8080);
server.addConnector(wsConnector);
ServerConnector wssConnector = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory,
HttpVersion.HTTP_1_1.asString()),
new HttpConnectionFactory(https_config)); // THIS WAS MISSING
wssConnector.setHost("localhost");
wssConnector.setPort(8443);
server.addConnector(wssConnector);
server.start();
server.join();
}

Related

Indy TLS Server "No shared cipher" using ECDH Keys

Hoping someone out there can help me with this one. Simple TIdHTTPServer with OpenSSL support used to decode TLS traffic from a client using ECDH-based keys.
Server key created with the following command:
openssl ecparam -name secp256k1 -genkey -noout -out key.pem
Server debug logs:
23:33:14.878 SSL status: "before/accept initialization"
23:33:14.886 SSL status: "SSLv3 read client hello C"
23:33:14.886 SSL status: "error"
23:33:14.887 Connection from: 192.168.12.1:23727 Closed
23:33:14.887 EXCEPTION: Error accepting connection with SSL.
error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher
From this question, it seems like I need to call SSL_CTX_set_ecdh_auto(ctx,1)
SSL Server Initialization:
ServerIOHandler = new TIdServerIOHandlerSSLOpenSSL();
ServerIOHandler->SSLOptions->CertFile = CertPath;
ServerIOHandler->SSLOptions->KeyFile = KeyPath;
ServerIOHandler->SSLOptions->RootCertFile = RootCertPath;
ServerIOHandler->SSLOptions->Method = sslvTLSv1_2;
ServerIOHandler->SSLOptions->Mode = sslmServer;
//ServerIOHandler->SSLOptions->CipherList = "";
ServerIOHandler->SSLOptions->VerifyDepth = 1;
ServerIOHandler->OnGetPassword = OnGetServerPassword;
ServerIOHandler->OnStatusInfo = SSL_Status;
TLSServer->Bindings->Add();
TLSServer->Bindings->Items[0]->IP = TLSServerInfo.AdapterIP;
TLSServer->Bindings->Items[0]->Port = TLSServerInfo.LocalPort;
TLSServer->DefaultPort = TLSServerInfo.LocalPort;
TLSServer->IOHandler = ServerIOHandler;
try {
PanelServer->Active = true;
}
catch (Exception &Ex) {
Msg = String(L"SSL Server Bound Exception: ") + Ex.Message;
}
I have followed these instructions to add SSL_CTX_set_ecdh_auto() to my IdSSLOpenSSLHeaders.pas file, but if I try to add an entry to call SSL_CTX_set_ecdh_auto() from my code, I get a "Call to undefined function 'SSL_CTX_set_ecdh_auto'" error.
I am running Indy 10.6.2.

SSL implementation with Tungstenite: SSL alert number 42

I created a working WebSocket server with async_tungstenite and async_std.
I now want to add SSL using async_native_tls.
If I understood correctly, this crates provides a function accept which takes a TcpStream, handles the TLS handshake and provides a TlsStream<TcpStream> which should behave like a TcpStream but handles the encryption and decryption behind the scene.
To test the server, I created a self-signed certificate.
Based on that, here is how the code handling new TCP connections evolved:
async fn accept_connection(stream: TcpStream, addr: SocketAddr) {
//Websocket stream
let accept_resut = async_tungstenite::accept_async(stream).await;
if let Err(err) = accept_resut {
println!(
"Error while trying to accept websocket: {}",
err.to_string()
);
panic!(err);
}
println!("New web socket: {}", addr);
}
async fn accept_connection(stream: TcpStream, addr: SocketAddr) {
//Open tls certificate !should be done one time and not for each connection!
let file = File::open("identity.pfx").await.unwrap();
let acceptor_result = TlsAcceptor::new(file, "glacon").await;
if let Err(err) = acceptor_result {
println!("Error while opening certificate: {}", err.to_string());
panic!(err);
}
let acceptor = acceptor_result.unwrap();
//Get a stream where tls is handled
let tls_stream_result = acceptor.accept(stream).await;
if let Err(err) = tls_stream_result {
println!("Error during tls handshake: {}", err.to_string());
panic!(err);
}
let tls_stream = tls_stream_result.unwrap();
//Websocket stream
let accept_resut = async_tungstenite::accept_async(tls_stream).await;
if let Err(err) = accept_resut {
println!(
"Error while trying to accept websocket: {}",
err.to_string()
);
panic!(err);
}
println!("New web socket: {}", addr);
}
With this implementation, I now call from a webpage
const sock = new WebSocket('wss://localhost:8020');
This results in the error:
Error while trying to accept websocket:
IO error: error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate:../ssl/record/rec_layer_s3.c:1543:SSL alert number 42
thread 'async-std/runtime' panicked at 'Box<Any>', src/main.rs:57:9
It seems like the handshake was successful as the error does not occur during the acceptor.accept. The error states that the certificate is not valid so here is how I created my self-signed certificate.
The openssl version is 1.1.1f
# Create a key
openssl req -nodes -new -key server.key -out server.csr
# Create the self-signed certificate
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
# Convert the certificate to pfx format
openssl pkcs12 -export -out identity.pfx -inkey server.key -in server.crt
I thought that this problem had to do with security feature from the browser as the "SSL alert number 42" seems to come from the client. I tried to disable this option in Firefox settings
Query OCSP responder servers to confirm the current validity of certificates
I also tried to add my server.crt to the Authorities of the certificate manager.
Neither of these worked.
The problem came from the security features of Firefox.
Firefox detects that the certificate is not signed by an authority and sends back an error.
It seems like adding the certificate to the known authorities does not work.
To avoid this issue, I found this thread which indicates that an exception should be added for the address and port of your development Websocket server.
Go to Settings > Certificates > View Certificates > Servers > Add Exception...
Type in your local server (for me localhost:8020).
Add exception.

PKIX path validation failed while connecting from Java

I have simple Java client to MQTT Mosquitto server:
public class TestMQTT3 {
public static void main(String[] args) {
System.out.println("Starting");
String serverUrl = "ssl://192.168.1.8:8887";
String path= "C:\\projects\\certs\\CA4\\";
String caFilePath =path+"cacert.pem";
String mqttUserName = "b";
String mqttPassword = "b";
MqttClient client;
try {
client = new MqttClient(serverUrl, "2");
MqttConnectOptions options = new MqttConnectOptions();
options.setUserName(mqttUserName);
options.setPassword(mqttPassword.toCharArray());
options.setConnectionTimeout(60);
options.setKeepAliveInterval(60);
options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1);
SSLSocketFactory socketFactory = getSocketFactory3(caFilePath);
options.setSocketFactory(socketFactory);
System.out.println("starting connect the server...");
client.connect(options);
System.out.println("connected!");
Thread.sleep(1000);
client.subscribe(
"/u/56ca327d17531d08e76bddd4a215e37f5fd6082f7442151c4d3f1d100a0ffd4e",
0);
client.disconnect();
System.out.println("disconnected!");
} catch (MqttException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private static SSLSocketFactory getSocketFactory3(final String caCrtFile) throws Exception
{
Security.addProvider(new BouncyCastleProvider());
// load CA certificate
X509Certificate caCert = null;
FileInputStream fis = new FileInputStream(caCrtFile);
BufferedInputStream bis = new BufferedInputStream(fis);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
while (bis.available() > 0)
{
caCert = (X509Certificate) cf.generateCertificate(bis);
System.out.println(caCert.toString());
}
// CA certificate is used to authenticate server
KeyStore caKs = KeyStore.getInstance(KeyStore.getDefaultType());
caKs.load(null, null);
caKs.setCertificateEntry("ca-certificate", caCert);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(caKs);
// finally, create SSL socket factory
SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(null, tmf.getTrustManagers(), null);
return context.getSocketFactory();
}
}
Trying to connect by using CA certificate:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
f6:7e:ef:1c:70:ef:30:64
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=US, ST=California, L=Hawthorne, O=PhilNet, OU=UN, CN=CN
Validity
Not Before: Jan 15 17:36:08 2020 GMT
Not After : Jan 14 17:36:08 2021 GMT
Subject: C=US, ST=California, L=Hawthorne, O=PhilNet, OU=UN, CN=CN
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:d2:65:49:db:fc:87:dd:36:8a:e0:27:e6:bb:66:
66:78:35:af:86:ae:d3:e5:e2:07:db:8e:51:f2:67:
06:22:78:99:b3:2f:81:14:a9:e7:28:7e:2a:96:8d:
fb:ec:29:64:39:5b:b7:d4:3c:22:b0:30:18:0d:e4:
c1:38:57:c2:ba:c5:09:11:12:46:8b:cc:06:08:0d:
e4:86:3f:98:e7:61:2d:d8:a9:40:34:e6:87:d7:7d:
c4:7c:62:51:78:b3:fd:d8:a6:1d:15:0b:80:fb:78:
29:59:9c:b7:30:ad:7e:92:f0:bc:94:3c:03:30:c1:
83:28:92:de:34:0b:68:8c:19:6e:d7:29:de:75:23:
59:8c:11:51:a8:84:69:32:d3:96:3d:eb:df:44:7b:
b6:85:2e:f4:af:98:a7:28:84:7b:7d:c9:56:89:66:
e0:e0:3d:63:ae:59:46:23:98:13:bc:af:72:7b:6f:
d5:a6:ec:3e:4e:56:2c:87:f6:70:ab:47:05:a3:4a:
1b:9e:2c:ec:52:7f:3e:7f:b9:a3:33:59:8a:1d:28:
cc:d4:39:0c:8b:f2:12:2d:82:09:63:bd:ae:b3:51:
c6:a4:ac:d3:ab:e4:31:de:b6:b0:11:85:90:36:33:
70:15:94:d0:54:ab:07:bb:a9:6a:63:3e:84:cc:5c:
c3:13
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
75:AF:4E:B9:E0:49:FE:62:C1:21:28:B0:77:38:36:02:22:2E:1B:8F
X509v3 Authority Key Identifier:
keyid:75:AF:4E:B9:E0:49:FE:62:C1:21:28:B0:77:38:36:02:22:2E:1B:8F
X509v3 Subject Alternative Name:
IP Address:192.168.1.8, DNS:glass
Signature Algorithm: sha1WithRSAEncryption
7b:af:79:85:a6:69:3f:00:3c:d3:f9:b7:9f:f6:31:8a:3d:fd:
7f:9e:63:8b:86:de:4e:34:34:11:b3:e1:73:3d:24:8d:06:e5:
ba:a6:91:ba:bc:0a:2f:b1:95:34:4b:c8:cd:cf:6b:31:14:17:
5f:a4:4e:74:8d:07:01:fb:7f:2b:0d:fc:6a:35:85:46:ea:ba:
fc:98:92:de:69:4d:53:f2:c8:99:e9:bd:fa:df:a7:cf:aa:48:
c0:6f:93:ba:cd:79:43:8a:89:8b:e7:bd:99:dd:11:31:c8:5f:
76:a8:fd:99:13:1c:a0:8b:e3:86:72:62:cf:09:7c:de:9d:cf:
db:0b:fc:81:62:1c:32:b0:81:52:58:d9:2f:0b:44:fa:8a:59:
5f:23:b2:01:f0:8e:53:c3:8d:36:1c:25:0b:b5:80:67:95:85:
66:74:8a:08:cc:9c:dc:c1:c6:f6:4b:b7:4b:a3:1a:2d:41:19:
20:7b:54:f0:f1:fe:22:e6:55:7e:14:07:66:77:36:2c:17:ee:
31:33:40:c8:b9:6e:fa:c4:98:86:3a:6f:ba:c0:72:22:75:6c:
5f:4f:94:07:c9:cf:6d:67:61:ff:e9:da:88:95:68:72:78:43:
59:f2:e9:5b:0f:95:d6:7e:33:19:70:23:b4:1e:dd:c9:db:d4:
bc:16:d6:9e
Got error:
starting connect the server...
MqttException (0) - javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:736)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1640)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
at org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule.start(SSLNetworkModule.java:149)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:722)
... 1 more
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:362)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:270)
at sun.security.validator.Validator.validate(Validator.java:262)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:330)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:237)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1622)
... 10 more
Caused by: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:159)
at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:85)
at java.security.cert.CertPathValidator.validate(CertPathValidator.java:292)
at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:357)
... 16 more
What I do wrong and how to solve problem?

X509Certificate2 the server mode SSL must use a certificate with the associated private key

I use SslStream to build a web server. However, the code below throws an exception when AuthenticateAsServer.
static X509Certificate cert;
protected virtual Stream GetStream(TcpClient client)
{
var ss = new SslStream(client.GetStream(), false);
if (cert == null)
{
cert = X509Certificate2.CreateFromCertFile("test.cer");
}
ss.AuthenticateAsServer(cert, false, System.Security.Authentication.SslProtocols.Tls, true);
return ss;
}
I've already used X509Certificate2 to load the cert file why it still throw the exception (The server mode SSL must use a certificate with the associated private key)?
The cert file was created using the following command:
makecert
-pe Exportable private key
-n "CN=localhost" Subject name
-ss my Certificate store name
-sr LocalMachine Certificate store location
-a sha1 Signature algorithm
-sky signature Subject key type is for signature purposes
-r Make a self-signed cert
"test.cer" Output filename
makecert.exe -r -pe -n "CN=localhost" -sky exchange -sv server.pvk server.cer
pvk2pfx -pvk server.pvk -spc server.cer -pfx server.pfx -pi <password>
var certificate = new X509Certificate("path\server.pfx", "password");

Openssl Errors on port change

Very simple question. I'm trying to us OpenSSL in Ruby to connect to a service, but getting errors.
When I use the following command:
openssl s_client -ssl3 -showcerts -connect example.com:443 -tls1 -cipher 'DHE-RSA-AES256-SHA' -nbio_test -state
It works great! The cert shows up with all the correct information.
But when I do:
openssl s_client -ssl3 -showcerts -connect example.com:13902 -tls1 -cipher 'DHE-RSA-AES256-SHA' -nbio_test -state
I get the following errors:
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:error in SSLv3 write client hello B
write W BLOCK
SSL_connect:SSLv3 write client hello B
SSL3 alert read:fatal:handshake failure
SSL_connect:failed in SSLv3 read server hello A
140735228511072:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1275:SSL alert number 40
140735228511072:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:598:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1408456884
Timeout : 7200 (sec)
Verify return code: 0 (ok)
---
The only thing that changed between the two commands is the port. The other flags were copied directly from the successful request. In other words I first did openssl s_client -showcerts -connect example.com:443 and then copied the ssl version, tls version, and cipher into the second two commands.
Is this a problem with openssl or the certificate? And if it is a problem with the certificate, how do I fix it? (and what is it?)
PS. I was able to connect in Java just fine using the following code, but still have to find a Ruby way:
public static void main(String[] args) throws NoSuchAlgorithmException,
KeyManagementException, IOException {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs,
String authType) {
}
public void checkServerTrusted(X509Certificate[] certs,
String authType) {
}
} };
final SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
URL url = new URL("https://example.com:13902");
URLConnection con = url.openConnection();
final Reader reader = new InputStreamReader(con.getInputStream());
final BufferedReader br = new BufferedReader(reader);
String line = "";
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}
Figured it out. Was specifying both tls1 and ssl3. Needed to just specify tls1. Thanks Aria!