00001
00002
00003
00004
00005
00006
00007
00008
#include <openssl/bn.h>
00009
#include "wvdiffiehellman.h"
00010
00011
#include "strutils.h"
00012
00013 WvDiffieHellman::WvDiffieHellman(
const unsigned char *_key,
int _keylen,
00014 BN_ULONG _generator) :
00015 generator(_generator),
log("Diffie-Hellman",
WvLog::Debug)
00016 {
00017
int problems;
00018
int check;
00019 {
00020
info = DH_new();
00021
info->p = BN_bin2bn(_key, _keylen, NULL);
00022
00023
00024
00025
00026
00027
info->g = BN_new();
00028 BN_set_word(
info->g,
generator);
00029
00030
00031
00032
00033
00034 }
00035
00036 check = BN_mod_word(
info->p, 24);
00037 DH_check(
info, &problems);
00038
if (problems & DH_CHECK_P_NOT_PRIME)
00039
log(WvLog::Error,
"Using a composite number for authentication.\n");
00040
if (problems & DH_CHECK_P_NOT_SAFE_PRIME)
00041
log(WvLog::Error,
"Using an unsafe prime number for authentication.\n");
00042
if (problems & DH_NOT_SUITABLE_GENERATOR)
00043
log(WvLog::Error,
"Can you just use 2 instead of %s (%s)!!\n",
00044 BN_bn2hex(
info->g), check);
00045
if (problems & DH_UNABLE_TO_CHECK_GENERATOR)
00046
log(WvLog::Notice,
"Using a strange argument for diffie-hellman.\n");
00047 DH_generate_key(
info);
00048 }
00049
00050 int WvDiffieHellman::pub_key_len()
00051 {
00052
return BN_num_bytes(
info->pub_key);
00053 }
00054
00055 int WvDiffieHellman::get_public_value(
WvBuf &outbuf,
int len)
00056 {
00057
int key_len = BN_num_bytes(
info->pub_key);
00058
if (key_len < len)
00059 len = key_len;
00060
00061
00062
unsigned char *foo = (
unsigned char*)alloca(key_len);
00063 BN_bn2bin(
info->pub_key, foo);
00064 outbuf.
put(foo, len);
00065
00066
return len;
00067 }
00068
00069 bool WvDiffieHellman::create_secret(
WvBuf &inbuf, size_t in_len,
WvBuf& outbuf)
00070 {
00071
unsigned char *foo = (
unsigned char *)alloca(DH_size(
info));
00072
log(
"My public value\n%s\nYour public value\n%s\n",BN_bn2hex(
info->pub_key),
00073
hexdump_buffer(inbuf.
peek(0, in_len), in_len,
false));
00074
int len = DH_compute_key (foo, BN_bin2bn(inbuf.
get(in_len), in_len, NULL),
00075
info);
00076
00077 outbuf.
put(foo, len);
00078
00079
log(
"Shared secret\n%s\n",
hexdump_buffer(outbuf.
peek(0, len), len,
false));
00080
00081
return true;
00082 }