X-Git-Url: https://www.tinc-vpn.org/git/browse?a=blobdiff_plain;f=lib%2Fprivatekey.cc;fp=lib%2Fprivatekey.cc;h=4cda7a526f84fb7cd036a010b57089314393542e;hb=401e0b5e1d97ded0e2c7415c6dd0f94ee6bfb470;hp=0000000000000000000000000000000000000000;hpb=0f3083b8693bfaddc4bf3fd6ce7174ac06afa958;p=fides diff --git a/lib/privatekey.cc b/lib/privatekey.cc new file mode 100644 index 0000000..4cda7a5 --- /dev/null +++ b/lib/privatekey.cc @@ -0,0 +1,126 @@ +/* fides.cc - Light-weight, decentralised trust and authorisation management + Copyright (C) 2008-2009 Guus Sliepen + + 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 . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fides.h" +#include "privatekey.h" + +using namespace std; + +static Botan::AutoSeeded_RNG rng; + +namespace fides { + /// \class privatekey + /// + /// \brief Representation of a public/private keypair. + /// + /// With a private key we can create a signature of a statement, + /// so that others who have the corresponding public key + /// can ascertain that the statement was really made by us. + + privatekey::privatekey(): priv(0) { + } + + privatekey::~privatekey() { + delete priv; + pub = 0; + } + + /// Generates a new public/private keypair. + // + /// @param field OID of the field to generate a key in. + void privatekey::generate(const std::string &field) { + Botan::EC_Domain_Params domain = Botan::get_EC_Dom_Pars_by_oid(field); + pub = priv = new Botan::ECDSA_PrivateKey(rng, domain); + } + + /// Generates a new public/private keypair. + // + /// This function uses standard NIST fields. + /// @param bits Desired size of the keys. + /// Allowed values are 112, 128, 160, 192, 224, 256, 384 and 521. + /// Keys less than 160 bits are considered weak. + /// Keys greater than 224 bits are considered very strong. + void privatekey::generate(unsigned int bits) { + switch(bits) { + case 112: return generate("1.3.132.0.6"); + case 128: return generate("1.3.132.0.28"); + case 160: return generate("1.3.132.0.9"); + case 192: return generate("1.3.132.0.31"); + case 224: return generate("1.3.132.0.32"); + case 256: return generate("1.3.132.0.10"); + case 384: return generate("1.3.132.0.34"); + case 521: return generate("1.3.132.0.35"); + default: throw fides::exception("Unsupported number of bits for private key"); + } + } + + /// Loads a private key from a stream. + // + /// @param in Stream to read from. + void privatekey::load_private(std::istream &in) { + try { + Botan::DataSource_Stream stream(in); + pub = priv = dynamic_cast(Botan::PKCS8::load_key(stream, rng, "")); + } catch(Botan::Exception &e) { + throw fides::exception(e.what()); + } + } + + /// Loads a private key from a file. + // + /// @param filename Name of the file to read from. + void privatekey::load_private(const std::string &filename) { + ifstream in(filename.c_str()); + load_private(in); + } + + /// Saves the private key to a stream. + // + /// @param out Stream to write to. + void privatekey::save_private(std::ostream &out) const { + out << Botan::PKCS8::PEM_encode(*priv); + } + + /// Saves the private key to a file. + // + /// @param filename Name of the file to write to. + void privatekey::save_private(const std::string &filename) const { + ofstream out(filename.c_str()); + save_private(out); + } + + /// Signs a statement with this private key. + // + /// @param statement The statement that is to be signed. + /// @return A string containing the signature. + string privatekey::sign(const std::string &statement) const { + auto_ptr signer(Botan::get_pk_signer(*priv, "EMSA1(SHA-512)")); + Botan::SecureVector sig = signer->sign_message((const Botan::byte *)statement.data(), statement.size(), rng); + return string((const char *)sig.begin(), (size_t)sig.size()); + } +}