]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/modules/ssl.h
9830b1ca6b24a8b289d03218616470be6feed47f
[user/henk/code/inspircd.git] / include / modules / ssl.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2006 Craig Edwards <craigedwards@brainbox.cc>
6  *
7  * This file is part of InspIRCd.  InspIRCd is free software: you can
8  * redistribute it and/or modify it under the terms of the GNU General Public
9  * License as published by the Free Software Foundation, version 2.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20
21 #pragma once
22
23 #include <map>
24 #include <string>
25 #include "iohook.h"
26
27 /** ssl_cert is a class which abstracts SSL certificate
28  * and key information.
29  *
30  * Because gnutls and openssl represent key information in
31  * wildly different ways, this class allows it to be accessed
32  * in a unified manner. These classes are attached to ssl-
33  * connected local users using SSLCertExt
34  */
35 class ssl_cert : public refcountbase
36 {
37  public:
38         std::string dn;
39         std::string issuer;
40         std::string error;
41         std::string fingerprint;
42         bool trusted, invalid, unknownsigner, revoked;
43
44         ssl_cert() : trusted(false), invalid(true), unknownsigner(true), revoked(false) {}
45
46         /** Get certificate distinguished name
47          * @return Certificate DN
48          */
49         const std::string& GetDN()
50         {
51                 return dn;
52         }
53
54         /** Get Certificate issuer
55          * @return Certificate issuer
56          */
57         const std::string& GetIssuer()
58         {
59                 return issuer;
60         }
61
62         /** Get error string if an error has occured
63          * @return The error associated with this users certificate,
64          * or an empty string if there is no error.
65          */
66         const std::string& GetError()
67         {
68                 return error;
69         }
70
71         /** Get key fingerprint.
72          * @return The key fingerprint as a hex string.
73          */
74         const std::string& GetFingerprint()
75         {
76                 return fingerprint;
77         }
78
79         /** Get trust status
80          * @return True if this is a trusted certificate
81          * (the certificate chain validates)
82          */
83         bool IsTrusted()
84         {
85                 return trusted;
86         }
87
88         /** Get validity status
89          * @return True if the certificate itself is
90          * correctly formed.
91          */
92         bool IsInvalid()
93         {
94                 return invalid;
95         }
96
97         /** Get signer status
98          * @return True if the certificate appears to be
99          * self-signed.
100          */
101         bool IsUnknownSigner()
102         {
103                 return unknownsigner;
104         }
105
106         /** Get revokation status.
107          * @return True if the certificate is revoked.
108          * Note that this only works properly for GnuTLS
109          * right now.
110          */
111         bool IsRevoked()
112         {
113                 return revoked;
114         }
115
116         bool IsCAVerified()
117         {
118                 return trusted && !invalid && !revoked && !unknownsigner && error.empty();
119         }
120
121         std::string GetMetaLine()
122         {
123                 std::stringstream value;
124                 bool hasError = !error.empty();
125                 value << (IsInvalid() ? "v" : "V") << (IsTrusted() ? "T" : "t") << (IsRevoked() ? "R" : "r")
126                         << (IsUnknownSigner() ? "s" : "S") << (hasError ? "E" : "e") << " ";
127                 if (hasError)
128                         value << GetError();
129                 else
130                         value << GetFingerprint() << " " << GetDN() << " " << GetIssuer();
131                 return value.str();
132         }
133 };
134
135 class SSLIOHook : public IOHook
136 {
137  public:
138         SSLIOHook(Module* mod, const std::string& Name)
139                 : IOHook(mod, Name, IOHook::IOH_SSL)
140         {
141         }
142
143         /**
144          * Get the client certificate from a socket
145          * @param sock The socket to get the certificate from, must be using this IOHook
146          * @return The SSL client certificate information
147          */
148         virtual ssl_cert* GetCertificate(StreamSocket* sock) = 0;
149
150         /**
151          * Get the fingerprint of a client certificate from a socket
152          * @param sock The socket to get the certificate fingerprint from, must be using this IOHook
153          * @return The fingerprint of the SSL client certificate sent by the peer,
154          * empty if no cert was sent
155          */
156         std::string GetFingerprint(StreamSocket* sock)
157         {
158                 ssl_cert* cert = GetCertificate(sock);
159                 if (cert)
160                         return cert->GetFingerprint();
161                 return "";
162         }
163 };
164
165 /** Helper functions for obtaining SSL client certificates and key fingerprints
166  * from StreamSockets
167  */
168 class SSLClientCert
169 {
170  public:
171         /**
172          * Get the client certificate from a socket
173          * @param sock The socket to get the certificate from, the socket does not have to use SSL
174          * @return The SSL client certificate information, NULL if the peer is not using SSL
175          */
176         static ssl_cert* GetCertificate(StreamSocket* sock)
177         {
178                 IOHook* iohook = sock->GetIOHook();
179                 if ((!iohook) || (iohook->type != IOHook::IOH_SSL))
180                         return NULL;
181
182                 SSLIOHook* ssliohook = static_cast<SSLIOHook*>(iohook);
183                 return ssliohook->GetCertificate(sock);
184         }
185
186         /**
187          * Get the fingerprint of a client certificate from a socket
188          * @param sock The socket to get the certificate fingerprint from, the
189          * socket does not have to use SSL
190          * @return The key fingerprint from the SSL certificate sent by the peer,
191          * empty if no cert was sent or the peer is not using SSL
192          */
193         static std::string GetFingerprint(StreamSocket* sock)
194         {
195                 ssl_cert* cert = SSLClientCert::GetCertificate(sock);
196                 if (cert)
197                         return cert->GetFingerprint();
198                 return "";
199         }
200 };
201
202 /** Get certificate from a user (requires m_sslinfo) */
203 struct UserCertificateRequest : public Request
204 {
205         User* const user;
206         ssl_cert* cert;
207
208         UserCertificateRequest(User* u, Module* Me, Module* info = ServerInstance->Modules->Find("m_sslinfo.so"))
209                 : Request(Me, info, "GET_USER_CERT"), user(u), cert(NULL)
210         {
211                 Send();
212         }
213
214         std::string GetFingerprint()
215         {
216                 if (cert)
217                         return cert->GetFingerprint();
218                 return "";
219         }
220 };