Clean up the namespace.
[fides] / lib / publickey.cc
1 /* fides.cc - 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 #include <iostream>
19 #include <fstream>
20 #include <string>
21 #include <botan/types.h>
22 #include <botan/botan.h>
23 #include <botan/ecdsa.h>
24 #include <botan/look_pk.h>
25 #include <botan/lookup.h>
26 #include <botan/filters.h>
27 #include <botan/sha2_32.h>
28 #include <list>
29
30 #include "fides.h"
31 #include "publickey.h"
32
33 using namespace std;
34
35 namespace Fides {
36         /// \class PublicKey
37         ///
38         /// \brief Representation of a public key.
39         ///
40         /// A public key is the counterpart of a private key that is held by some entity.
41         /// If we have a public key, we can verify signatures made by the corresponding private key.
42         /// Thus, we can ascertain if a statement, if it has been properly signed,
43         /// was indeed made by that entity.
44
45         PublicKey::PublicKey(): pub(0), trust(0) {
46         }
47
48         PublicKey::~PublicKey() {
49                 delete pub;
50         }
51
52         /// Loads a public key from a stream.
53         //
54         /// @param in Stream to read from.
55         void PublicKey::load(std::istream &in) {
56                 try {
57                         Botan::DataSource_Stream source(in);
58                         pub = dynamic_cast<Botan::ECDSA_PublicKey *>(Botan::X509::load_key(source));
59                 } catch(Botan::Exception &e) {
60                         throw Fides::exception(e.what());
61                 }
62         }
63
64         /// Loads a public key from a file.
65         //
66         /// @param filename Name of the file to read the key from.
67         void PublicKey::load(const std::string &filename) {
68                 ifstream in(filename.c_str());
69                 load(in);
70         }
71
72         /// Saves the public key to a stream.
73         //
74         /// @param out Stream to write to.
75         void PublicKey::save(std::ostream &out) const {
76                 out << to_string();
77         }
78
79         /// Saves the public key to a file.
80         //
81         /// @param filename Name of the file to save the key to.
82         void PublicKey::save(const std::string &filename) const {
83                 ofstream out(filename.c_str());
84                 save(out);
85         }
86
87         /// Loads a public key from a string.
88         //
89         /// @param in String containing a public key in textual format.
90         void PublicKey::from_string(const std::string &in) {
91                 try {
92                         Botan::DataSource_Memory source(in);
93                         pub = dynamic_cast<Botan::ECDSA_PublicKey *>(Botan::X509::load_key(source));
94                 } catch(Botan::Exception &e) {
95                         throw Fides::exception(e.what());
96                 }
97         }
98
99         /// Write the public key to a string.
100         //
101         /// @return String containing the public key in textual format.
102         string PublicKey::to_string() const {
103                 return Botan::X509::PEM_encode(*pub);
104         }
105
106         /// Get the fingerprint of the public key.
107         //
108         /// @param bits Number of bits from the fingerprint to return.
109         ///             The number will be rounded down to the nearest multiple of 8.
110         /// @return String containing the fingerprint.
111         string PublicKey::fingerprint(unsigned int bits) const {
112                 // TODO: find out if there is a standard way to get a hash of an ECDSA public key
113                 Botan::SHA_256 sha256;
114                 Botan::SecureVector<Botan::byte> hash = sha256.process(Botan::X509::PEM_encode(*pub));
115                 return string((const char *)hash.begin(), bits / 8);
116         }
117
118         /// Verify the signature of a statement.
119         //
120         /// @param statement The statement. This is the data that has been signed.
121         /// @param signature The signature of the statement.
122         /// @return Returns true if the signature is indeed a valid signature, made by this public key, of the statement.
123         ///         Return false otherwise.
124         bool PublicKey::verify(const std::string &statement, const std::string &signature) const {
125                 auto_ptr<Botan::PK_Verifier> verifier(Botan::get_pk_verifier(*pub, "EMSA1(SHA-512)"));
126                 verifier->update((const Botan::byte *)statement.data(), statement.size());
127                 Botan::SecureVector<Botan::byte> sig;
128                 sig.set((const Botan::byte *)signature.data(), signature.size());
129                 return verifier->check_signature(sig);
130         }
131 }