WvStreams
wvdsa.cc
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"
13 
14 /***** WvDSAKey *****/
15 
16 WvDSAKey::WvDSAKey(const WvDSAKey &k)
17 {
18  if (k.prv)
19  init(k.private_str(), true);
20  else
21  init(k.public_str(), false);
22 }
23 
24 
25 WvDSAKey::WvDSAKey(struct dsa_st *_dsa, bool priv)
26 {
27  if (_dsa == NULL)
28  {
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;
35  }
36 
37  dsa = _dsa;
38  pub = hexifypub(dsa);
39  if (priv)
40  prv = hexifyprv(dsa);
41 }
42 
43 
44 WvDSAKey::WvDSAKey(WvStringParm keystr, bool priv)
45 {
46  init(keystr, priv);
47 }
48 
49 
50 WvDSAKey::WvDSAKey(int bits)
51 {
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);
56 }
57 
58 
59 WvDSAKey::~WvDSAKey()
60 {
61  if (dsa)
62  DSA_free(dsa);
63 }
64 
65 
66 bool WvDSAKey::isok() const
67 {
68  return dsa && !errstring;
69 }
70 
71 
72 void WvDSAKey::init(WvStringParm keystr, bool priv)
73 {
74  // Start out with everything nulled out...
75  dsa = NULL;
76  pub = WvString::null;
77  prv = WvString::null;
78 
79  // unhexify the supplied key
80  WvDynBuf keybuf;
81  if (!WvHexDecoder().flushstrbuf(keystr, keybuf, true) ||
82  keybuf.used() == 0)
83  {
84  seterr("DSA key is not a valid hex string");
85  return;
86  }
87 
88  size_t keylen = keybuf.used();
89  const unsigned char *key = keybuf.get(keylen);
90 
91  // create the DSA struct
92  if (priv)
93  {
94  dsa = wv_d2i_DSAPrivateKey(NULL, &key, keylen);
95  if (dsa != NULL)
96  {
97  prv = keystr;
98  pub = hexifypub(dsa);
99  }
100  }
101  else
102  {
103  dsa = wv_d2i_DSAPublicKey(NULL, &key, keylen);
104  if (dsa != NULL)
105  {
106  prv = WvString::null;
107  pub = keystr;
108  }
109  }
110  if (dsa == NULL)
111  seterr("DSA key is invalid");
112 }
113 
114 
115 
117 {
118  FILE *fp = tmpfile();
119  const EVP_CIPHER *enc;
120 
121  if (!fp)
122  {
123  seterr("Unable to open temporary file!");
124  return WvString::null;
125  }
126 
127  if (privkey)
128  {
129  enc = EVP_get_cipherbyname("dsa");
130  PEM_write_DSAPrivateKey(fp, dsa, enc,
131  NULL, 0, NULL, NULL);
132  }
133  else
134  {
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);
138  }
139 
140  WvDynBuf b;
141  size_t len;
142 
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);
148 
149  return b.getstr();
150 }
151 
152 
153 
154 WvString WvDSAKey::hexifypub(struct dsa_st *dsa)
155 {
156  WvDynBuf keybuf;
157 
158  assert(dsa);
159 
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);
165 
166  return WvString(WvHexEncoder().strflushbuf(keybuf, true));
167 }
168 
169 
170 WvString WvDSAKey::hexifyprv(struct dsa_st *dsa)
171 {
172  WvDynBuf keybuf;
173 
174  assert(dsa);
175 
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);
180 
181  return WvString(WvHexEncoder().strflushbuf(keybuf, true));
182 }
183 
wvhex.h
WvBufBaseCommonImpl::get
const T * get(size_t count)
Reads exactly the specified number of elements and returns a pointer to a storage location owned by t...
Definition: wvbufbase.h:114
WvBufBaseCommonImpl::alloc
T * alloc(size_t count)
Allocates exactly the specified number of elements and returns a pointer to an UNINITIALIZED storage ...
Definition: wvbufbase.h:379
WvBufBaseCommonImpl::unalloc
void unalloc(size_t count)
Unallocates exactly the specified number of elements by removing them from the buffer and releasing t...
Definition: wvbufbase.h:421
WvBufBase< unsigned char >::getstr
WvString getstr()
Returns the entire buffer as a null-terminated WvString.
Definition: wvbuffer.cc:17
WvErrorBase::seterr
virtual void seterr(int _errnum)
Set the errnum variable – we have an error.
Definition: wverror.cc:144
WvString
WvString is an implementation of a simple and efficient printable-string class.
Definition: wvstring.h:329
WvDSAKey::getpem
WvString getpem(bool privkey)
Retrieve the public or private key in PEM encoded format.
Definition: wvdsa.cc:116
WvDSAKey::isok
virtual bool isok() const
By default, returns true if geterr() == 0.
Definition: wvdsa.cc:66
WvHexEncoder
A hex encoder.
Definition: wvhex.h:21
WvHexDecoder
A hex decoder.
Definition: wvhex.h:53
WvDynBufBase< unsigned char >
WvBufBaseCommonImpl::used
size_t used() const
Returns the number of elements in the buffer currently available for reading.
Definition: wvbufbase.h:92
WvDSAKey
An DSA public key or public/private key pair that can be used for encryption.
Definition: wvdsa.h:23
WvDSAKey::public_str
WvString public_str() const
Retrieve the public key as a hexified string.
Definition: wvdsa.h:62
WvDSAKey::private_str
WvString private_str() const
Retrieve the private key as a hexified string returns WvString::null if there is only a public key.
Definition: wvdsa.h:56