1 /**
2  * SSL support.
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;
15 
16 import ae.net.asockets : IConnection, ConnectionAdapter;
17 
18 /// Abstract interface for an SSL context provider.
19 class SSLProvider
20 {
21 	/// Create an SSL context of the given kind (client or server).
22 	abstract SSLContext createContext(SSLContext.Kind kind);
23 
24 	/// Create a connection adapter using the given context.
25 	abstract SSLAdapter createAdapter(SSLContext context, IConnection next);
26 }
27 
28 /// The default (null) `SSLProvider` implementation.
29 /// Throws an assertion failure.
30 class NoSSLProvider : SSLProvider
31 {
32 	override SSLContext createContext(SSLContext.Kind kind)
33 	{
34 		assert(false, "SSL implementation not set");
35 	} ///
36 
37 	override SSLAdapter createAdapter(SSLContext context, IConnection next)
38 	{
39 		assert(false, "SSL implementation not set");
40 	} ///
41 }
42 
43 enum SSLVersion
44 {
45 	unspecified,
46 	ssl3,
47 	tls1,
48 	tls11,
49 	tls12,
50 	tls13,
51 }
52 
53 /// Abstract interface for an SSL context.
54 abstract class SSLContext
55 {
56 	/// Context kind.
57 	enum Kind
58 	{
59 		client, ///
60 		server,	///
61 	}
62 
63 	/// Whether to verify the peer certificate.
64 	enum Verify
65 	{
66 		none,    /// Do not verify or require.
67 		verify,  /// Verify the certificate if one is specified.
68 		require, /// Require a certificate and verify it.
69 	}
70 
71 	abstract void setCipherList(string[] ciphers);                /// Configure OpenSSL-like cipher list.
72 	abstract void enableDH(int bits);                             /// Enable Diffie-Hellman key exchange with the specified key size.
73 	abstract void enableECDH();                                   /// Enable elliptic-curve DH key exchange.
74 	abstract void setCertificate(string path);                    /// Load and use a local certificate from the given file.
75 	abstract void setPrivateKey(string path);                     /// Load and use the certificate private key from the given file.
76 	abstract void setPreSharedKey(string id, const(ubyte)[] key); /// Use a pre-shared key instead of using certificate-based peer verification.
77 	abstract void setPeerVerify(Verify verify);                   /// Configure peer certificate verification.
78 	abstract void setPeerRootCertificate(string path);            /// Require that peer certificates are signed by the specified root certificate.
79 	abstract void setFlags(int);                                  /// Configure provider-specific flags.
80 	abstract void setMinimumVersion(SSLVersion);                  /// Set the minimum protocol version.
81 	abstract void setMaximumVersion(SSLVersion);                  /// Set the maximum protocol version.
82 }
83 
84 /// Base class for a connection adapter with TLS encryption.
85 abstract class SSLAdapter : ConnectionAdapter
86 {
87 	this(IConnection next) { super(next); } ///
88 
89 	/// Specifies the expected host name (used for peer verification).
90 	abstract void setHostName(string hostname, ushort port = 0, string service = null);
91 
92 	/// Retrieves the host (local) certificate.
93 	abstract SSLCertificate getHostCertificate();
94 
95 	/// Retrieves the peer (remote) certificate.
96 	abstract SSLCertificate getPeerCertificate();
97 }
98 
99 /// Abstract interface for an SSL certificate.
100 abstract class SSLCertificate
101 {
102 	/// Returns the full certificate subject name.
103 	abstract string getSubjectName();
104 }
105 
106 /// The current global SSL provider.
107 SSLProvider ssl;
108 
109 static this()
110 {
111 	assert(!ssl);
112 	ssl = new NoSSLProvider();
113 }