Saner handling if config.mk doesn't exist: use a default config.defaults.mk.
[wvstreams.git] / crypto / wvdiffiehellman.cc
blob7c0bf329fa7f941988e7ae68914badcd1253a324
1 /*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 2003 Net Integration Technologies, Inc.
5 * Diffie-Hellman shared secret handshake.
6 */
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
30 #include <openssl/bn.h>
31 #include <stdlib.h>
33 #include "wvdiffiehellman.h"
34 #include "strutils.h"
36 WvDiffieHellman::WvDiffieHellman(const unsigned char *_key, int _keylen,
37 BN_ULONG _generator) :
38 generator(_generator), log("Diffie-Hellman", WvLog::Debug)
40 int problems;
41 int check;
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;
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;
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);
73 int WvDiffieHellman::pub_key_len()
75 return BN_num_bytes(info->pub_key);
78 int WvDiffieHellman::get_public_value(WvBuf &outbuf, int len)
80 int key_len = BN_num_bytes(info->pub_key);
81 if (key_len < len)
82 len = key_len;
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);
89 return len;
92 bool WvDiffieHellman::create_secret(WvBuf &inbuf, size_t in_len, WvBuf& outbuf)
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);
100 outbuf.put(foo, len);
102 log("Shared secret\n%s\n",hexdump_buffer(outbuf.peek(0, len), len, false));
104 return true;