Saner handling if config.mk doesn't exist: use a default config.defaults.mk.
[wvstreams.git] / crypto / wvdsa.cc
blob8973d340c69aae1d70688a8dbed1f3dc02f16765
1 /*
2 * Worldvisions Tunnel Vision Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4 *
5 * DSA cryptography abstractions.
6 */
7 #include <assert.h>
8 #include <openssl/dsa.h>
9 #include <openssl/pem.h>
10 #include "wvsslhacks.h"
11 #include "wvdsa.h"
12 #include "wvhex.h"
14 /***** WvDSAKey *****/
16 WvDSAKey::WvDSAKey(const WvDSAKey &k)
18 if (k.prv)
19 init(k.private_str(), true);
20 else
21 init(k.public_str(), false);
25 WvDSAKey::WvDSAKey(struct dsa_st *_dsa, bool priv)
27 if (_dsa == NULL)
29 // assert(_dsa);
30 pub = WvString::null;
31 prv = WvString::null;
32 dsa = NULL;
33 seterr("Initializing with a NULL key.. are you insane?");
34 return;
37 dsa = _dsa;
38 pub = hexifypub(dsa);
39 if (priv)
40 prv = hexifyprv(dsa);
44 WvDSAKey::WvDSAKey(WvStringParm keystr, bool priv)
46 init(keystr, priv);
50 WvDSAKey::WvDSAKey(int bits)
52 dsa = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
53 DSA_generate_key(dsa);
54 pub = hexifypub(dsa);
55 prv = hexifyprv(dsa);
59 WvDSAKey::~WvDSAKey()
61 if (dsa)
62 DSA_free(dsa);
66 bool WvDSAKey::isok() const
68 return dsa && !errstring;
72 void WvDSAKey::init(WvStringParm keystr, bool priv)
74 // Start out with everything nulled out...
75 dsa = NULL;
76 pub = WvString::null;
77 prv = WvString::null;
79 // unhexify the supplied key
80 WvDynBuf keybuf;
81 if (!WvHexDecoder().flushstrbuf(keystr, keybuf, true) ||
82 keybuf.used() == 0)
84 seterr("DSA key is not a valid hex string");
85 return;
88 size_t keylen = keybuf.used();
89 const unsigned char *key = keybuf.get(keylen);
91 // create the DSA struct
92 if (priv)
94 dsa = wv_d2i_DSAPrivateKey(NULL, &key, keylen);
95 if (dsa != NULL)
97 prv = keystr;
98 pub = hexifypub(dsa);
101 else
103 dsa = wv_d2i_DSAPublicKey(NULL, &key, keylen);
104 if (dsa != NULL)
106 prv = WvString::null;
107 pub = keystr;
110 if (dsa == NULL)
111 seterr("DSA key is invalid");
116 WvString WvDSAKey::getpem(bool privkey)
118 FILE *fp = tmpfile();
119 const EVP_CIPHER *enc;
121 if (!fp)
123 seterr("Unable to open temporary file!");
124 return WvString::null;
127 if (privkey)
129 enc = EVP_get_cipherbyname("dsa");
130 PEM_write_DSAPrivateKey(fp, dsa, enc,
131 NULL, 0, NULL, NULL);
133 else
135 // We should write out the Public Key, which is the DSA Public
136 // key, as well as the DH generator information.
137 // PEM_write_DSAPublicKey(fp, dsa);
140 WvDynBuf b;
141 size_t len;
143 rewind(fp);
144 while ((len = fread(b.alloc(1024), 1, 1024, fp)) > 0)
145 b.unalloc(1024 - len);
146 b.unalloc(1024 - len);
147 fclose(fp);
149 return b.getstr();
154 WvString WvDSAKey::hexifypub(struct dsa_st *dsa)
156 WvDynBuf keybuf;
158 assert(dsa);
160 size_t size = i2d_DSAPublicKey(dsa, NULL);
161 unsigned char *key = keybuf.alloc(size);
162 size_t newsize = i2d_DSAPublicKey(dsa, & key);
163 assert(size == newsize);
164 assert(keybuf.used() == size);
166 return WvString(WvHexEncoder().strflushbuf(keybuf, true));
170 WvString WvDSAKey::hexifyprv(struct dsa_st *dsa)
172 WvDynBuf keybuf;
174 assert(dsa);
176 size_t size = i2d_DSAPrivateKey(dsa, NULL);
177 unsigned char *key = keybuf.alloc(size);
178 size_t newsize = i2d_DSAPrivateKey(dsa, & key);
179 assert(size == newsize);
181 return WvString(WvHexEncoder().strflushbuf(keybuf, true));