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 /// Abstract interface for an SSL context.
44 abstract class SSLContext
45 {
46 	/// Context kind.
47 	enum Kind
48 	{
49 		client, ///
50 		server,	///
51 	}
52 
53 	/// Whether to verify the peer certificate.
54 	enum Verify
55 	{
56 		none,    /// Do not verify or require.
57 		verify,  /// Verify the certificate if one is specified.
58 		require, /// Require a certificate and verify it.
59 	}
60 
61 	abstract void setCipherList(string[] ciphers);                /// Configure OpenSSL-like cipher list.
62 	abstract void enableDH(int bits);                             /// Enable Diffie-Hellman key exchange with the specified key size.
63 	abstract void enableECDH();                                   /// Enable elliptic-curve DH key exchange.
64 	abstract void setCertificate(string path);                    /// Load and use a local certificate from the given file.
65 	abstract void setPrivateKey(string path);                     /// Load and use the certificate private key from the given file.
66 	abstract void setPreSharedKey(string id, const(ubyte)[] key); /// Use a pre-shared key instead of using certificate-based peer verification.
67 	abstract void setPeerVerify(Verify verify);                   /// Configure peer certificate verification.
68 	abstract void setPeerRootCertificate(string path);            /// Require that peer certificates are signed by the specified root certificate.
69 	abstract void setFlags(int);                                  /// Configure provider-specific flags.
70 }
71 
72 /// Base class for a connection adapter with TLS encryption.
73 abstract class SSLAdapter : ConnectionAdapter
74 {
75 	this(IConnection next) { super(next); } ///
76 
77 	/// Specifies the expected host name (used for peer verification).
78 	abstract void setHostName(string hostname, ushort port = 0, string service = null);
79 
80 	/// Retrieves the host (local) certificate.
81 	abstract SSLCertificate getHostCertificate();
82 
83 	/// Retrieves the peer (remote) certificate.
84 	abstract SSLCertificate getPeerCertificate();
85 }
86 
87 /// Abstract interface for an SSL certificate.
88 abstract class SSLCertificate
89 {
90 	/// Returns the full certificate subject name.
91 	abstract string getSubjectName();
92 }
93 
94 /// The current global SSL provider.
95 SSLProvider ssl;
96 
97 static this()
98 {
99 	assert(!ssl);
100 	ssl = new NoSSLProvider();
101 }