WvStreams
wvdiffiehellman.cc
1 /*
2  * Worldvisions Weaver Software:
3  * Copyright (C) 2003 Net Integration Technologies, Inc.
4  *
5  * Diffie-Hellman shared secret handshake.
6  */
7 
8 #include "wvautoconf.h"
9 #ifdef __GNUC__
10 # define alloca __builtin_alloca
11 #else
12 # ifdef _MSC_VER
13 # include <malloc.h>
14 # define alloca _alloca
15 # else
16 # if HAVE_ALLOCA_H
17 # include <alloca.h>
18 # else
19 # ifdef _AIX
20 #pragma alloca
21 # else
22 # ifndef alloca /* predefined by HP cc +Olibcalls */
23 char *alloca ();
24 # endif
25 # endif
26 # endif
27 # endif
28 #endif
29 
30 #include <openssl/bn.h>
31 #include <stdlib.h>
32 
33 #include "wvdiffiehellman.h"
34 #include "strutils.h"
35 
36 WvDiffieHellman::WvDiffieHellman(const unsigned char *_key, int _keylen,
37  BN_ULONG _generator) :
38  generator(_generator), log("Diffie-Hellman", WvLog::Debug)
39 {
40  int problems;
41  int check;
42  {
43  info = DH_new();
44  info->p = BN_bin2bn(_key, _keylen, NULL);
45 // info->p->top = 0;
46 // info->p->dmax = _keylen * 8 / BN_BITS2;
47 // info->p->neg = 0;
48 // info->p->flags = 0;
49 
50  info->g = BN_new();
51  BN_set_word(info->g, generator);
52 // info->g->d = &generator;
53 // info->g->top = 0;
54 // info->g->dmax = 1;
55 // info->g->neg = 0;
56 // info->g->flags = 0;
57  }
58 
59  check = BN_mod_word(info->p, 24);
60  DH_check(info, &problems);
61  if (problems & DH_CHECK_P_NOT_PRIME)
62  log(WvLog::Error, "Using a composite number for authentication.\n");
63  if (problems & DH_CHECK_P_NOT_SAFE_PRIME)
64  log(WvLog::Error,"Using an unsafe prime number for authentication.\n");
65  if (problems & DH_NOT_SUITABLE_GENERATOR)
66  log(WvLog::Error, "Can you just use 2 instead of %s (%s)!!\n",
67  BN_bn2hex(info->g), check);
68  if (problems & DH_UNABLE_TO_CHECK_GENERATOR)
69  log(WvLog::Notice, "Using a strange argument for diffie-hellman.\n");
70  DH_generate_key(info);
71 }
72 
73 int WvDiffieHellman::pub_key_len()
74 {
75  return BN_num_bytes(info->pub_key);
76 }
77 
78 int WvDiffieHellman::get_public_value(WvBuf &outbuf, int len)
79 {
80  int key_len = BN_num_bytes(info->pub_key);
81  if (key_len < len)
82  len = key_len;
83 
84  // alloca is stack allocated, don't free it.
85  unsigned char *foo = (unsigned char*)alloca(key_len);
86  BN_bn2bin(info->pub_key, foo);
87  outbuf.put(foo, len);
88 
89  return len;
90 }
91 
92 bool WvDiffieHellman::create_secret(WvBuf &inbuf, size_t in_len, WvBuf& outbuf)
93 {
94  unsigned char *foo = (unsigned char *)alloca(DH_size(info));
95  log("My public value\n%s\nYour public value\n%s\n",BN_bn2hex(info->pub_key),
96  hexdump_buffer(inbuf.peek(0, in_len), in_len, false));
97  int len = DH_compute_key (foo, BN_bin2bn(inbuf.get(in_len), in_len, NULL),
98  info);
99 
100  outbuf.put(foo, len);
101 
102  log("Shared secret\n%s\n",hexdump_buffer(outbuf.peek(0, len), len, false));
103 
104  return true;
105 }
WvString hexdump_buffer(const void *buf, size_t len, bool charRep=true)
Produce a hexadecimal dump of the data buffer in 'buf' of length 'len'.
Definition: strutils.cc:245
Specialization of WvBufBase for unsigned char type buffers intended for use with raw memory buffers...
Definition: wvbuf.h:22
const T * peek(int offset, size_t count)
Returns a const pointer into the buffer at the specified offset to the specified number of elements w...
Definition: wvbufbase.h:225
const T * get(size_t count)
Reads exactly the specified number of elements and returns a pointer to a storage location owned by t...
Definition: wvbufbase.h:114
A WvLog stream accepts log messages from applications and forwards them to all registered WvLogRcv's...
Definition: wvlog.h:56