1 /* fides.cc - Light-weight, decentralised trust and authorisation management
2 Copyright (C) 2008-2009 Guus Sliepen <guus@tinc-vpn.org>
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.
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.
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/>.
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>
31 #include "publickey.h"
38 /// \brief Representation of a public key.
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.
45 PublicKey::PublicKey(): pub(0), trust(0) {
48 PublicKey::~PublicKey() {
52 /// Loads a public key from a stream.
54 /// @param in Stream to read from.
55 void PublicKey::load(std::istream &in) {
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());
64 /// Loads a public key from a file.
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());
72 /// Saves the public key to a stream.
74 /// @param out Stream to write to.
75 void PublicKey::save(std::ostream &out) const {
79 /// Saves the public key to a file.
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());
87 /// Loads a public key from a string.
89 /// @param in String containing a public key in textual format.
90 void PublicKey::from_string(const std::string &in) {
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());
99 /// Write the public key to a string.
101 /// @return String containing the public key in textual format.
102 string PublicKey::to_string() const {
103 return Botan::X509::PEM_encode(*pub);
106 /// Get the fingerprint of the public key.
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);
118 /// Verify the signature of a statement.
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);
135 fides_publickey *fides_publickey_new() {
136 return new Fides::PublicKey();
139 void fides_publickey_free(fides_publickey *k) {
144 void fides_publickey_set_trust(fides_publickey *k, int trust) {
148 int fides_publickey_get_trust(fides_publickey *k) {
153 void fides_publickey_load(fides_publickey *k, const char *filename) {
157 void fides_publickey_save(fides_publickey *k, const char *filename) {
161 bool fides_publickey_verify(fides_publickey *k, const char *data, const char *signature) {
162 return k->verify(data, signature);
165 char *fides_publickey_to_string(fides_publickey *k) {
166 return strdup(k->to_string().c_str());
169 void fides_publickey_from_string(fides_publickey *k, const char *in) {
173 char *fides_publickey_fingerprint(fides_publickey *k, unsigned int bits) {
174 return strdup(k->fingerprint(bits).c_str());