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 */
23char *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
36WvDiffieHellman::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
74int 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
81int 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
98bool 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}
A WvLog stream accepts log messages from applications and forwards them to all registered WvLogRcv's.
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