Split the libary into multiple files, in general one per class.
[fides] / lib / publickey.cc
diff --git a/lib/publickey.cc b/lib/publickey.cc
new file mode 100644 (file)
index 0000000..7a8a16d
--- /dev/null
@@ -0,0 +1,131 @@
+/* fides.cc - Light-weight, decentralised trust and authorisation management
+   Copyright (C) 2008-2009  Guus Sliepen <guus@tinc-vpn.org>
+  
+   Fides is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of
+   the License, or (at your option) any later version.
+  
+   Fides is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+   GNU Lesser General Public License for more details.
+  
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <botan/types.h>
+#include <botan/botan.h>
+#include <botan/ecdsa.h>
+#include <botan/look_pk.h>
+#include <botan/lookup.h>
+#include <botan/filters.h>
+#include <botan/sha2_32.h>
+#include <list>
+
+#include "fides.h"
+#include "publickey.h"
+
+using namespace std;
+
+namespace fides {
+       /// \class publickey
+       ///
+       /// \brief Representation of a public key.
+       ///
+       /// A public key is the counterpart of a private key that is held by some entity.
+       /// If we have a public key, we can verify signatures made by the corresponding private key.
+       /// Thus, we can ascertain if a statement, if it has been properly signed,
+       /// was indeed made by that entity.
+
+       publickey::publickey(): pub(0), trust(0) {
+       }
+
+       publickey::~publickey() {
+               delete pub;
+       }
+
+       /// Loads a public key from a stream.
+       //
+       /// @param in Stream to read from.
+       void publickey::load(std::istream &in) {
+               try {
+                       Botan::DataSource_Stream source(in);
+                       pub = dynamic_cast<Botan::ECDSA_PublicKey *>(Botan::X509::load_key(source));
+               } catch(Botan::Exception &e) {
+                       throw fides::exception(e.what());
+               }
+       }
+
+       /// Loads a public key from a file.
+       //
+       /// @param filename Name of the file to read the key from.
+       void publickey::load(const std::string &filename) {
+               ifstream in(filename.c_str());
+               load(in);
+       }
+
+       /// Saves the public key to a stream.
+       //
+       /// @param out Stream to write to.
+       void publickey::save(std::ostream &out) const {
+               out << to_string();
+       }
+
+       /// Saves the public key to a file.
+       //
+       /// @param filename Name of the file to save the key to.
+       void publickey::save(const std::string &filename) const {
+               ofstream out(filename.c_str());
+               save(out);
+       }
+
+       /// Loads a public key from a string.
+       //
+       /// @param in String containing a public key in textual format.
+       void publickey::from_string(const std::string &in) {
+               try {
+                       Botan::DataSource_Memory source(in);
+                       pub = dynamic_cast<Botan::ECDSA_PublicKey *>(Botan::X509::load_key(source));
+               } catch(Botan::Exception &e) {
+                       throw fides::exception(e.what());
+               }
+       }
+
+       /// Write the public key to a string.
+       //
+       /// @return String containing the public key in textual format.
+       string publickey::to_string() const {
+               return Botan::X509::PEM_encode(*pub);
+       }
+
+       /// Get the fingerprint of the public key.
+       //
+       /// @param bits Number of bits from the fingerprint to return.
+       ///             The number will be rounded down to the nearest multiple of 8.
+       /// @return String containing the fingerprint.
+       string publickey::fingerprint(unsigned int bits) const {
+               // TODO: find out if there is a standard way to get a hash of an ECDSA public key
+               Botan::SHA_256 sha256;
+               Botan::SecureVector<Botan::byte> hash = sha256.process(Botan::X509::PEM_encode(*pub));
+               return string((const char *)hash.begin(), bits / 8);
+       }
+
+       /// Verify the signature of a statement.
+       //
+       /// @param statement The statement. This is the data that has been signed.
+       /// @param signature The signature of the statement.
+       /// @return Returns true if the signature is indeed a valid signature, made by this public key, of the statement.
+       ///         Return false otherwise.
+       bool publickey::verify(const std::string &statement, const std::string &signature) const {
+               auto_ptr<Botan::PK_Verifier> verifier(Botan::get_pk_verifier(*pub, "EMSA1(SHA-512)"));
+               verifier->update((const Botan::byte *)statement.data(), statement.size());
+               Botan::SecureVector<Botan::byte> sig;
+               sig.set((const Botan::byte *)signature.data(), signature.size());
+               return verifier->check_signature(sig);
+       }
+}