Clean up the namespace.
[fides] / lib / privatekey.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
29 #include "fides.h"
30 #include "privatekey.h"
31
32 using namespace std;
33
34 static Botan::AutoSeeded_RNG rng;
35
36 namespace Fides {
37         /// \class PrivateKey
38         ///
39         /// \brief Representation of a public/private keypair.
40         ///
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.
44
45         PrivateKey::PrivateKey(): priv(0) {
46         }
47
48         PrivateKey::~PrivateKey() {
49                 delete priv;
50                 pub = 0;
51         }
52
53         /// Generates a new public/private keypair.
54         //
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);
59         }
60
61         /// Generates a new public/private keypair.
62         //
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) {
69                 switch(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");
79                 }
80         }
81
82         /// Loads a private key from a stream.
83         //
84         /// @param in Stream to read from.
85         void PrivateKey::load_private(std::istream &in) {
86                 try {
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());
91                 }
92         }
93
94         /// Loads a private key from a file.
95         //
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());
99                 load_private(in);
100         }
101
102         /// Saves the private key to a stream.
103         //
104         /// @param out Stream to write to.
105         void PrivateKey::save_private(std::ostream &out) const {
106                 out << Botan::PKCS8::PEM_encode(*priv);
107         }
108
109         /// Saves the private key to a file.
110         //
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());
114                 save_private(out);
115         }
116
117         /// Signs a statement with this private key.
118         //
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());
125         }
126 }