Add comments so doxygen can generate a reference manual.
[fides] / lib / fides.h
1 /* fides.h - Light-weight, decentralised trust and authorisation management
2    Copyright (C) 2008-2009  Guus Sliepen <guus@tinc-vpn.org>
3   
4    Fides is free software; you can redistribute it and/or modify
5    it under the terms of the GNU Lesser General Public License as
6    published by the Free Software Foundation; either version 2.1 of
7    the License, or (at your option) any later version.
8   
9    Fides is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12    GNU Lesser General Public License for more details.
13   
14    You should have received a copy of the GNU Lesser General Public
15    License along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifndef __FIDES_H__
19 #define __FIDES_H__
20
21 #include <stdexcept>
22 #include <regex.h>
23 #include <botan/botan.h>
24 #include <botan/ecdsa.h>
25 #include <sys/time.h>
26 #include <map>
27
28 class fides {
29         std::string homedir;
30         std::string certdir;
31         std::string obsoletedir;
32         std::string keydir;
33
34         bool firstrun;
35         struct timeval latest;
36         static Botan::AutoSeeded_RNG rng;
37
38         public:
39         // Utility functions
40
41         static std::string b64encode(const std::string &in);
42         static std::string b64decode(const std::string &in);
43         static std::string hexencode(const std::string &in);
44         static std::string hexdecode(const std::string &in);
45
46         /// Compiled regular expression.
47
48         /// This class holds a compiled regular expression,
49         /// which can be used to match arbitrary strings to.
50         /// It is a wrapper for the POSIX regex functions
51         /// regcomp() and regexec().
52         class regexp {
53                 regex_t comp;
54
55                 public:
56                 static const int EXTENDED = REG_EXTENDED;
57                 static const int ICASE = REG_ICASE;
58                 static const int NOSUB = REG_NOSUB;
59                 static const int NEWLINE = REG_NEWLINE;
60
61                 static const int NOTBOL = REG_NOTBOL;
62                 static const int NOTEOL = REG_NOTEOL;
63
64                 /// Construct a compiled regular expression.
65                 ///
66                 /// @param exp    Regular expression to compile.
67                 /// @param cflags Bitwise OR of options to apply when compiling the regular expression:
68                 ///               - fides::regexp::EXTENDED
69                 ///                 Use POSIX Extended Regular Expression syntax when interpreting exp.
70                 ///               - fides::regexp::ICASE
71                 ///                 Make the expression case-insensitive.
72                 ///               - fides::regexp::NOSUB
73                 ///                 Disable support for substring addressing.
74                 ///               - fides::regexp::NEWLINE
75                 ///                 Do not treat the newline character as the start or end of a line.
76                 regexp(const std::string &exp, int cflags = 0) {
77                         int err = regcomp(&comp, exp.c_str(), cflags);
78                         if(err)
79                                 throw exception("Could not compile regular expression");
80                 }
81
82                 ~regexp() {
83                         regfree(&comp);
84                 }
85
86                 /// Test whether a string matches the regular expression.
87                 ///
88                 /// @param in     String to test.
89                 /// @param eflags Bitwise OR of options to apply when matching the string:
90                 ///               - fides::regexp::NOTBOL
91                 ///                 Do not treat the start of the string as the start of a line.
92                 ///               - fides::regexp::NOTEOL
93                 ///                 Do not treat the end of the string as the end of a line.
94                 /// @return True if the string matches the regular expression, false otherwise.
95                 bool match(const std::string &in, int eflags = 0) {
96                         return regexec(&comp, in.c_str(), 0, 0, eflags) == 0;
97                 }
98         };
99
100         class exception: public std::runtime_error {
101                 public:
102                 exception(const std::string reason): runtime_error(reason) {}
103         };
104
105         // Objects manipulated by fides
106
107         class publickey {
108                 protected:
109                 Botan::ECDSA_PublicKey *pub;
110
111                 public:
112                 publickey();
113                 ~publickey();
114
115                 int trust;
116                 void load(std::istream &in);
117                 void save(std::ostream &out) const;
118                 void load(const std::string &filename);
119                 void save(const std::string &filename) const;
120                 bool verify(const std::string &data, const std::string &signature) const;
121                 std::string to_string() const;
122                 void from_string(const std::string &in);
123                 std::string fingerprint(unsigned int bits = 64) const;
124         };
125
126         class privatekey: public publickey {
127                 Botan::ECDSA_PrivateKey *priv;
128
129                 public:
130                 privatekey();
131                 ~privatekey();
132
133                 void load_private(std::istream &in);
134                 void save_private(std::ostream &out) const;
135                 void load_private(const std::string &filename);
136                 void save_private(const std::string &filename) const;
137                 void generate(const std::string &field);
138                 void generate(unsigned int bits = 224);
139                 std::string sign(const std::string &data) const;
140         };
141
142         class certificate {
143                 friend class fides;
144
145                 /// Public key that signed this certificate.
146                 const publickey *signer;
147                 struct timeval timestamp;
148                 std::string statement;
149                 std::string signature;
150
151                 public:
152                 certificate(const publickey *pub, struct timeval timestamp, const std::string &statement, const std::string &signature);
153                 certificate(const privatekey *priv, struct timeval timestamp, const std::string &statement);
154
155                 std::string to_string() const;
156                 std::string fingerprint(unsigned int bits = 64) const;
157                 bool validate() const;
158         };
159
160         // Fides class itself
161
162         private:
163         privatekey mykey;
164         std::map<std::string, publickey *> keys;
165         std::map<std::string, certificate *> certs;
166
167         void merge(certificate *cert);
168         void merge(publickey *key);
169
170         public:
171         fides(const std::string &homedir = "");
172         ~fides();
173
174         bool is_firstrun() const;
175         bool fsck() const;
176         std::string get_homedir() const;
177
178         void sign(const std::string &statement);
179
180         void allow(const std::string &statement, const publickey *key = 0);
181         void dontcare(const std::string &statement, const publickey *key = 0);
182         void deny(const std::string &statement, const publickey *key = 0);
183         bool is_allowed(const std::string &statement, const publickey *key = 0) const;
184         bool is_denied(const std::string &statement, const publickey *key = 0) const;
185
186         void auth_stats(const std::string &statement, int &self, int &trusted, int &all) const;
187         void trust(const publickey *key);
188         void dctrust(const publickey *key);
189         void distrust(const publickey *key);
190         bool is_trusted(const publickey *key) const;
191         bool is_distrusted(const publickey *key) const;
192         publickey *find_key(const std::string &fingerprint) const;
193         void update_trust();
194
195         std::vector<const certificate *> find_certificates(const publickey *key, const std::string &statement) const;
196         std::vector<const certificate *> find_certificates(const std::string &statement) const;
197         std::vector<const certificate *> find_certificates(const publickey *key) const;
198
199         const certificate *import_certificate(const std::string &certificate);
200         std::string export_certificate(const certificate *) const;
201
202         const publickey *import_key(const std::string &key);
203         std::string export_key(const publickey *key) const;
204
205         void import_all(std::istream &in);
206         void export_all(std::ostream &out) const;
207
208         certificate *certificate_from_string(const std::string &certificate);
209         certificate *certificate_load(const std::string &filename);
210         void certificate_save(const certificate *cert, const std::string &filename) const;
211
212 };
213
214 #endif