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 }