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 package(ae):
22 
23 version (SSL_test)
24 	void testSSL(SSLProvider ssl) {}
25 else:
26 
27 import std.stdio : stderr;
28 
29 void testSSL(SSLProvider ssl)
30 {
31 	import std.algorithm.searching : startsWith;
32 	debug(SSL) import std.stdio : stderr;
33 
34 	void testServer(string host, ushort port = 443)
35 	{
36 		stderr.writeln("Testing: ", host);
37 		auto c = new TcpConnection;
38 		auto ctx = ssl.createContext(SSLContext.Kind.client);
39 		ctx.setPeerVerify(SSLContext.Verify.require);
40 		auto s = ssl.createAdapter(ctx, c);
41 		Data allData;
42 
43 		s.handleConnect =
44 		{
45 			debug(SSL) stderr.writeln("Connected!");
46 			s.send(Data("GET / HTTP/1.0\r\nHost: " ~ host ~ "\r\n\r\n"));
47 		};
48 		s.handleReadData = (Data data)
49 		{
50 			debug(SSL) { stderr.write(cast(string)data.contents); stderr.flush(); }
51 			allData ~= data;
52 		};
53 		s.handleDisconnect = (string reason, DisconnectType type)
54 		{
55 			debug(SSL) { stderr.writeln(reason); }
56 			enforce(type == DisconnectType.graceful, "Unexpected disconnection: " ~ reason);
57 			enforce((cast(string)allData.contents).startsWith("HTTP/1.1 200 OK\r\n"), "Unexpected response");
58 		};
59 		s.setHostName(host);
60 		c.connect(host, port);
61 		socketManager.loop();
62 	}
63 
64 	testServer(              "expired.badssl.com").assertThrown;
65 	testServer(           "wrong.host.badssl.com").assertThrown;
66 	testServer(          "self-signed.badssl.com").assertThrown;
67 	testServer(       "untrusted-root.badssl.com").assertThrown;
68 	// testServer(              "revoked.badssl.com").assertThrown; // TODO!
69 	// testServer(         "pinning-test.badssl.com").assertThrown; // TODO!
70 
71 	// testServer(       "no-common-name.badssl.com").assertNotThrown; // Currently expired
72 	// testServer(           "no-subject.badssl.com").assertNotThrown; // Currently expired
73 	// testServer(     "incomplete-chain.badssl.com").assertNotThrown; // TODO?
74 
75 	testServer(               "sha256.badssl.com").assertNotThrown;
76 	testServer(               "sha384.badssl.com").assertNotThrown;
77 	testServer(               "sha512.badssl.com").assertNotThrown;
78 
79 	testServer(            "1000-sans.badssl.com").assertNotThrown;
80 	testServer(           "10000-sans.badssl.com").assertThrown;
81 
82 	testServer(               "ecc256.badssl.com").assertNotThrown;
83 	testServer(               "ecc384.badssl.com").assertNotThrown;
84 
85 	testServer(              "rsa2048.badssl.com").assertNotThrown;
86 	testServer(              "rsa4096.badssl.com").assertNotThrown;
87 	testServer(              "rsa8192.badssl.com").assertNotThrown;
88 
89 	testServer(  "extended-validation.badssl.com").assertNotThrown;
90 
91 	testServer(                  "cbc.badssl.com").assertNotThrown;
92 	testServer(              "rc4-md5.badssl.com").assertThrown;
93 	testServer(                  "rc4.badssl.com").assertThrown;
94 	testServer(                 "3des.badssl.com").assertThrown;
95 	testServer(                 "null.badssl.com").assertThrown;
96 
97 	testServer(          "mozilla-old.badssl.com").assertNotThrown; // Watch me, browsers may drop support soon
98 	testServer( "mozilla-intermediate.badssl.com").assertNotThrown;
99 	testServer(       "mozilla-modern.badssl.com").assertNotThrown;
100 
101 	testServer(                "dh480.badssl.com").assertThrown;
102 	testServer(                "dh512.badssl.com").assertThrown;
103 	testServer(               "dh1024.badssl.com").assertThrown;
104 	testServer(               "dh2048.badssl.com").assertThrown;
105 
106 	testServer(    "dh-small-subgroup.badssl.com").assertThrown;
107 	testServer(         "dh-composite.badssl.com").assertThrown;
108 
109 	testServer(           "static-rsa.badssl.com").assertNotThrown;
110 
111 	testServer(             "tls-v1-0.badssl.com", 1010).assertThrown;
112 	testServer(             "tls-v1-1.badssl.com", 1011).assertThrown;
113 	testServer(             "tls-v1-2.badssl.com", 1012).assertNotThrown;
114 }