wvdiffiehellman.cc

00001 /*
00002  * Worldvisions Weaver Software:
00003  * Copyright (C) 2003 Net Integration Technologies, Inc.
00004  *
00005  * Diffie-Hellman shared secret handshake.
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 /* predefined by HP cc +Olibcalls */
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 //      info->p->top = 0;
00045 //      info->p->dmax = _keylen * 8 / BN_BITS2;
00046 //      info->p->neg = 0;
00047 //      info->p->flags = 0;
00048 
00049         info->g = BN_new();
00050         BN_set_word(info->g, generator);
00051 //      info->g->d = &generator;
00052 //      info->g->top = 0;
00053 //      info->g->dmax = 1;
00054 //      info->g->neg = 0;
00055 //      info->g->flags = 0;
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     // alloca is stack allocated, don't free it.
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 }

Generated on Fri Oct 5 18:20:27 2007 for WvStreams by  doxygen 1.5.3