8 #include <openssl/rsa.h>
9 #include <openssl/pem.h>
10 #include "wvsslhacks.h"
13 #include "wvfileutils.h"
18 : debug(
"RSA",
WvLog::Debug5)
24 WvRSAKey::WvRSAKey(
const WvRSAKey &k)
25 : debug(
"RSA",
WvLog::Debug5)
30 rsa = RSAPublicKey_dup(k.rsa);
32 rsa = RSAPrivateKey_dup(k.rsa);
36 WvRSAKey::WvRSAKey(
struct rsa_st *_rsa,
bool _priv)
37 : debug(
"RSA",
WvLog::Debug5)
42 debug(
"Initializing with a NULL key.. are you insane?\n");
51 WvRSAKey::WvRSAKey(WvStringParm keystr,
bool _priv)
52 : debug(
"RSA",
WvLog::Debug5)
57 decode(RsaHex, keystr);
59 decode(RsaPubHex, keystr);
65 WvRSAKey::WvRSAKey(
int bits)
66 : debug(
"RSA",
WvLog::Debug5)
68 rsa = RSA_generate_key(bits, 0x10001, NULL, NULL);
80 bool WvRSAKey::isok()
const
82 return rsa && (!priv || RSA_check_key(rsa) == 1);
99 debug(WvLog::Warning,
"Tried to encode RSA key, but RSA key is "
104 if (mode == RsaHex || mode == RsaPubHex)
108 if (mode == RsaHex && priv)
110 size_t size = i2d_RSAPrivateKey(rsa, NULL);
111 unsigned char *key = keybuf.
alloc(size);
112 size_t newsize = i2d_RSAPrivateKey(rsa, & key);
113 assert(size == newsize);
117 size_t size = i2d_RSAPublicKey(rsa, NULL);
118 unsigned char *key = keybuf.
alloc(size);
119 size_t newsize = i2d_RSAPublicKey(rsa, & key);
120 assert(size == newsize);
127 BIO *bufbio = BIO_new(BIO_s_mem());
129 const EVP_CIPHER *enc = EVP_get_cipherbyname(
"rsa");
132 PEM_write_bio_RSAPrivateKey(bufbio, rsa, enc,
133 NULL, 0, NULL, NULL);
134 else if (mode == RsaPubPEM)
135 PEM_write_bio_RSAPublicKey(bufbio, rsa);
137 debug(WvLog::Warning,
"Should never happen: tried to encode RSA "
138 "key with unsupported mode.");
140 BIO_get_mem_ptr(bufbio, &bm);
141 buf.put(bm->data, bm->length);
160 debug(
"Decoding RSA key.\n");
164 debug(
"Replacing already existent RSA key.\n");
172 if (mode == RsaHex || mode == RsaPubHex)
179 debug(
"Couldn't unhexify RSA key.\n");
183 size_t keylen = keybuf.
used();
184 const unsigned char *key = keybuf.
get(keylen);
189 rsa = wv_d2i_RSAPrivateKey(NULL, &key, keylen);
193 rsa = wv_d2i_RSAPublicKey(NULL, &key, keylen);
200 BIO *membuf = BIO_new(BIO_s_mem());
201 BIO_write(membuf, encoded.
get(encoded.
used()), encoded.
used());
205 rsa = PEM_read_bio_RSAPrivateKey(membuf, NULL, NULL, NULL);
208 else if (mode == RsaPubPEM)
209 rsa = PEM_read_bio_RSAPublicKey(membuf, NULL, NULL, NULL);
211 debug(WvLog::Warning,
"Should never happen: tried to encode RSA "
212 "key with unsupported mode.");
214 BIO_free_all(membuf);
222 mode(_mode), key(_key)
224 if (key.isok() && key.rsa != NULL)
225 rsasize = RSA_size(key.rsa);
231 WvRSAEncoder::~WvRSAEncoder()
258 const size_t maxchunklen = rsasize - 12;
260 while ((chunklen = in.
used()) != 0)
262 if (chunklen >= maxchunklen)
263 chunklen = maxchunklen;
268 const unsigned char *data = in.
get(chunklen);
269 unsigned char *crypt = out.
alloc(rsasize);
270 size_t cryptlen = (mode ==
Encrypt) ?
271 RSA_public_encrypt(chunklen,
272 const_cast<unsigned char*
>(data), crypt,
273 key.rsa, RSA_PKCS1_PADDING) :
274 RSA_private_encrypt(chunklen,
275 const_cast<unsigned char*
>(data), crypt,
276 key.rsa, RSA_PKCS1_PADDING);
277 if (cryptlen != rsasize)
288 const size_t chunklen = rsasize;
289 while (in.
used() >= chunklen)
292 const unsigned char *crypt = in.
get(chunklen);
293 unsigned char *data = out.
alloc(rsasize);
294 int cryptlen = (mode ==
Decrypt) ?
295 RSA_private_decrypt(chunklen,
296 const_cast<unsigned char*
>(crypt), data,
297 key.rsa, RSA_PKCS1_PADDING) :
298 RSA_public_decrypt(chunklen,
299 const_cast<unsigned char*
>(crypt), data,
300 key.rsa, RSA_PKCS1_PADDING);
307 out.
unalloc(rsasize - cryptlen);
321 WvRSAStream::WvRSAStream(
WvStream *_cloned,
326 readchain.append(
new WvRSAEncoder(readmode, _my_key),
true);
327 writechain.append(
new WvRSAEncoder(writemode, _their_key),
true);
328 if (_my_key.isok() && _my_key.rsa)
329 min_readsize = RSA_size(_my_key.rsa);