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  BIGNUM *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  BIGNUM *g = BN_new();
51  BN_set_word(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  DH_set0_pqg(info, p, NULL, g);
59 
60  check = BN_mod_word(p, 24);
61  DH_check(info, &problems);
62  if (problems & DH_CHECK_P_NOT_PRIME)
63  log(WvLog::Error, "Using a composite number for authentication.\n");
64  if (problems & DH_CHECK_P_NOT_SAFE_PRIME)
65  log(WvLog::Error,"Using an unsafe prime number for authentication.\n");
66  if (problems & DH_NOT_SUITABLE_GENERATOR)
67  log(WvLog::Error, "Can you just use 2 instead of %s (%s)!!\n",
68  BN_bn2hex(g), check);
69  if (problems & DH_UNABLE_TO_CHECK_GENERATOR)
70  log(WvLog::Notice, "Using a strange argument for diffie-hellman.\n");
71  DH_generate_key(info);
72 }
73 
74 int WvDiffieHellman::pub_key_len()
75 {
76  const BIGNUM *pub_key = NULL;
77  DH_get0_key(info, &pub_key, NULL);
78  return BN_num_bytes(pub_key);
79 }
80 
81 int WvDiffieHellman::get_public_value(WvBuf &outbuf, int len)
82 {
83  const BIGNUM *pub_key = NULL;
84  DH_get0_key(info, &pub_key, NULL);
85 
86  int key_len = BN_num_bytes(pub_key);
87  if (key_len < len)
88  len = key_len;
89 
90  // alloca is stack allocated, don't free it.
91  unsigned char *foo = (unsigned char*)alloca(key_len);
92  BN_bn2bin(pub_key, foo);
93  outbuf.put(foo, len);
94 
95  return len;
96 }
97 
98 bool WvDiffieHellman::create_secret(WvBuf &inbuf, size_t in_len, WvBuf& outbuf)
99 {
100  const BIGNUM *pub_key = NULL;
101  DH_get0_key(info, &pub_key, NULL);
102  unsigned char *foo = (unsigned char *)alloca(DH_size(info));
103  log("My public value\n%s\nYour public value\n%s\n",BN_bn2hex(pub_key),
104  hexdump_buffer(inbuf.peek(0, in_len), in_len, false));
105  int len = DH_compute_key (foo, BN_bin2bn(inbuf.get(in_len), in_len, NULL),
106  info);
107 
108  outbuf.put(foo, len);
109 
110  log("Shared secret\n%s\n",hexdump_buffer(outbuf.peek(0, len), len, false));
111 
112  return true;
113 }
WvBufBaseCommonImpl::get
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
WvLog
A WvLog stream accepts log messages from applications and forwards them to all registered WvLogRcv's.
Definition: wvlog.h:56
WvBufBase< unsigned char >
Specialization of WvBufBase for unsigned char type buffers intended for use with raw memory buffers.
Definition: wvbuf.h:22
hexdump_buffer
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
WvBufBaseCommonImpl::peek
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