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>
30 #include "privatekey.h"
34 static Botan::AutoSeeded_RNG rng;
39 /// \brief Representation of a public/private keypair.
41 /// With a private key we can create a signature of a statement,
42 /// so that others who have the corresponding public key
43 /// can ascertain that the statement was really made by us.
45 PrivateKey::PrivateKey(): priv(0) {
48 PrivateKey::~PrivateKey() {
53 /// Generates a new public/private keypair.
55 /// @param field OID of the field to generate a key in.
56 void PrivateKey::generate(const std::string &field) {
57 Botan::EC_Domain_Params domain = Botan::get_EC_Dom_Pars_by_oid(field);
58 pub = priv = new Botan::ECDSA_PrivateKey(rng, domain);
61 /// Generates a new public/private keypair.
63 /// This function uses standard NIST fields.
64 /// @param bits Desired size of the keys.
65 /// Allowed values are 112, 128, 160, 192, 224, 256, 384 and 521.
66 /// Keys less than 160 bits are considered weak.
67 /// Keys greater than 224 bits are considered very strong.
68 void PrivateKey::generate(unsigned int bits) {
70 case 112: return generate("1.3.132.0.6");
71 case 128: return generate("1.3.132.0.28");
72 case 160: return generate("1.3.132.0.9");
73 case 192: return generate("1.3.132.0.31");
74 case 224: return generate("1.3.132.0.32");
75 case 256: return generate("1.3.132.0.10");
76 case 384: return generate("1.3.132.0.34");
77 case 521: return generate("1.3.132.0.35");
78 default: throw Fides::exception("Unsupported number of bits for private key");
82 /// Loads a private key from a stream.
84 /// @param in Stream to read from.
85 void PrivateKey::load_private(std::istream &in) {
87 Botan::DataSource_Stream stream(in);
88 pub = priv = dynamic_cast<Botan::ECDSA_PrivateKey *>(Botan::PKCS8::load_key(stream, rng, ""));
89 } catch(Botan::Exception &e) {
90 throw Fides::exception(e.what());
94 /// Loads a private key from a file.
96 /// @param filename Name of the file to read from.
97 void PrivateKey::load_private(const std::string &filename) {
98 ifstream in(filename.c_str());
102 /// Saves the private key to a stream.
104 /// @param out Stream to write to.
105 void PrivateKey::save_private(std::ostream &out) const {
106 out << Botan::PKCS8::PEM_encode(*priv);
109 /// Saves the private key to a file.
111 /// @param filename Name of the file to write to.
112 void PrivateKey::save_private(const std::string &filename) const {
113 ofstream out(filename.c_str());
117 /// Signs a statement with this private key.
119 /// @param statement The statement that is to be signed.
120 /// @return A string containing the signature.
121 string PrivateKey::sign(const std::string &statement) const {
122 auto_ptr<Botan::PK_Signer> signer(Botan::get_pk_signer(*priv, "EMSA1(SHA-512)"));
123 Botan::SecureVector<Botan::byte> sig = signer->sign_message((const Botan::byte *)statement.data(), statement.size(), rng);
124 return string((const char *)sig.begin(), (size_t)sig.size());
130 fides_privatekey *fides_privatekey_new() {
131 return new Fides::PrivateKey();
134 void fides_privatekey_free(fides_privatekey *k) {
138 void fides_privatekey_load_public(fides_privatekey *k, const char *filename) {
142 void fides_privatekey_save_public(fides_privatekey *k, const char *filename) {
146 void fides_privatekey_load(fides_privatekey *k, const char *filename) {
147 k->load_private(filename);
150 void fides_privatekey_save(fides_privatekey *k, const char *filename) {
151 k->save_private(filename);
154 void fides_privatekey_generate_field(fides_privatekey *k, const char *field) {
158 void fides_privatekey_generate(fides_privatekey *k, unsigned int bits) {
162 char *fides_privatekey_sign(fides_privatekey *k, const char *data) {
163 return strdup(k->sign(data).c_str());