1 /**
2  * SSL tests.
3  *
4  * License:
5  *   This Source Code Form is subject to the terms of
6  *   the Mozilla Public License, v. 2.0. If a copy of
7  *   the MPL was not distributed with this file, You
8  *   can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * Authors:
11  *   Vladimir Panteleev <ae@cy.md>
12  */
13 
14 module ae.net.ssl.test;
15 
16 import std.exception;
17 
18 import ae.net.asockets;
19 import ae.net.ssl;
20 
21 version (SSL_test)
22 	void testSSL(SSLProvider ssl) {}
23 else:
24 
25 import std.stdio : stderr;
26 
27 void testSSL(SSLProvider ssl)
28 {
29 	import std.algorithm.searching : startsWith;
30 	debug(SSL) import std.stdio : stderr;
31 
32 	void testServer(string host, ushort port = 443)
33 	{
34 		stderr.writeln("Testing: ", host);
35 		auto c = new TcpConnection;
36 		auto ctx = ssl.createContext(SSLContext.Kind.client);
37 		ctx.setPeerVerify(SSLContext.Verify.require);
38 		auto s = ssl.createAdapter(ctx, c);
39 		Data allData;
40 
41 		s.handleConnect =
42 		{
43 			debug(SSL) stderr.writeln("Connected!");
44 			s.send(Data("GET / HTTP/1.0\r\nHost: " ~ host ~ "\r\n\r\n"));
45 		};
46 		s.handleReadData = (Data data)
47 		{
48 			debug(SSL) { stderr.write(cast(string)data.contents); stderr.flush(); }
49 			allData ~= data;
50 		};
51 		s.handleDisconnect = (string reason, DisconnectType type)
52 		{
53 			debug(SSL) { stderr.writeln(reason); }
54 			enforce(type == DisconnectType.graceful, "Unexpected disconnection: " ~ reason);
55 			enforce((cast(string)allData.contents).startsWith("HTTP/1.1 200 OK\r\n"), "Unexpected response");
56 		};
57 		s.setHostName(host);
58 		c.connect(host, port);
59 		socketManager.loop();
60 	}
61 
62 	testServer(              "expired.badssl.com").assertThrown;
63 	testServer(           "wrong.host.badssl.com").assertThrown;
64 	testServer(          "self-signed.badssl.com").assertThrown;
65 	testServer(       "untrusted-root.badssl.com").assertThrown;
66 	// testServer(              "revoked.badssl.com").assertThrown; // TODO!
67 	// testServer(         "pinning-test.badssl.com").assertThrown; // TODO!
68 
69 	// testServer(       "no-common-name.badssl.com").assertNotThrown; // Currently expired
70 	// testServer(           "no-subject.badssl.com").assertNotThrown; // Currently expired
71 	// testServer(     "incomplete-chain.badssl.com").assertNotThrown; // TODO?
72 
73 	testServer(               "sha256.badssl.com").assertNotThrown;
74 	testServer(               "sha384.badssl.com").assertNotThrown;
75 	testServer(               "sha512.badssl.com").assertNotThrown;
76 
77 	testServer(            "1000-sans.badssl.com").assertNotThrown;
78 	testServer(           "10000-sans.badssl.com").assertThrown;
79 
80 	testServer(               "ecc256.badssl.com").assertNotThrown;
81 	testServer(               "ecc384.badssl.com").assertNotThrown;
82 
83 	testServer(              "rsa2048.badssl.com").assertNotThrown;
84 	testServer(              "rsa4096.badssl.com").assertNotThrown;
85 	testServer(              "rsa8192.badssl.com").assertNotThrown;
86 
87 	testServer(  "extended-validation.badssl.com").assertNotThrown;
88 
89 	testServer(                  "cbc.badssl.com").assertNotThrown;
90 	testServer(              "rc4-md5.badssl.com").assertThrown;
91 	testServer(                  "rc4.badssl.com").assertThrown;
92 	testServer(                 "3des.badssl.com").assertThrown;
93 	testServer(                 "null.badssl.com").assertThrown;
94 
95 	testServer(          "mozilla-old.badssl.com").assertNotThrown; // Watch me, browsers may drop support soon
96 	testServer( "mozilla-intermediate.badssl.com").assertNotThrown;
97 	testServer(       "mozilla-modern.badssl.com").assertNotThrown;
98 
99 	testServer(                "dh480.badssl.com").assertThrown;
100 	testServer(                "dh512.badssl.com").assertThrown;
101 	testServer(               "dh1024.badssl.com").assertThrown;
102 	testServer(               "dh2048.badssl.com").assertThrown;
103 
104 	testServer(    "dh-small-subgroup.badssl.com").assertThrown;
105 	testServer(         "dh-composite.badssl.com").assertThrown;
106 
107 	testServer(           "static-rsa.badssl.com").assertNotThrown;
108 
109 	testServer(             "tls-v1-0.badssl.com", 1010).assertThrown;
110 	testServer(             "tls-v1-1.badssl.com", 1011).assertThrown;
111 	testServer(             "tls-v1-2.badssl.com", 1012).assertNotThrown;
112 }