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 setPeerVerify(Verify verify);        /// Configure peer certificate verification.
67 	abstract void setPeerRootCertificate(string path); /// Require that peer certificates are signed by the specified root certificate.
68 	abstract void setFlags(int);                       /// Configure provider-specific flags.
69 }
70 
71 /// Base class for a connection adapter with TLS encryption.
72 abstract class SSLAdapter : ConnectionAdapter
73 {
74 	this(IConnection next) { super(next); } ///
75 
76 	/// Specifies the expected host name (used for peer verification).
77 	abstract void setHostName(string hostname, ushort port = 0, string service = null);
78 
79 	/// Retrieves the host (local) certificate.
80 	abstract SSLCertificate getHostCertificate();
81 
82 	/// Retrieves the peer (remote) certificate.
83 	abstract SSLCertificate getPeerCertificate();
84 }
85 
86 /// Abstract interface for an SSL certificate.
87 abstract class SSLCertificate
88 {
89 	/// Returns the full certificate subject name.
90 	abstract string getSubjectName();
91 }
92 
93 /// The current global SSL provider.
94 SSLProvider ssl;
95 
96 static this()
97 {
98 	assert(!ssl);
99 	ssl = new NoSSLProvider();
100 }