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 {
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; // Currently expired
75 		// testServer(               "sha512.badssl.com").assertNotThrown; // Currently expired
76 
77 		// testServer(            "1000-sans.badssl.com").assertNotThrown; // Currently expired
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; // Currently expired - https://github.com/chromium/badssl.com/issues/516
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 	}
113 }
114 else
115 	void testSSL(SSLProvider ssl) {}