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