diff options
author | lloyd <[email protected]> | 2006-05-18 18:33:19 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2006-05-18 18:33:19 +0000 |
commit | a2c99d3270eb73ef2db5704fc54356c6b75096f8 (patch) | |
tree | ad3d6c4fcc8dd0f403f8105598943616246fe172 /modules/es_egd/es_egd.cpp |
Initial checkin1.5.6
Diffstat (limited to 'modules/es_egd/es_egd.cpp')
-rw-r--r-- | modules/es_egd/es_egd.cpp | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/modules/es_egd/es_egd.cpp b/modules/es_egd/es_egd.cpp new file mode 100644 index 000000000..cf46b15d2 --- /dev/null +++ b/modules/es_egd/es_egd.cpp @@ -0,0 +1,91 @@ +/************************************************* +* EGD EntropySource Source File * +* (C) 1999-2006 The Botan Project * +*************************************************/ + +#include <botan/es_egd.h> +#include <botan/conf.h> +#include <botan/bit_ops.h> +#include <botan/parsing.h> +#include <cstring> + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> + +#ifndef PF_LOCAL + #define PF_LOCAL PF_UNIX +#endif + +namespace Botan { + +/************************************************* +* EGD_EntropySource Constructor * +*************************************************/ +EGD_EntropySource::EGD_EntropySource(const std::string& egd_paths) + { + std::vector<std::string> path_list = split_on(egd_paths, ':'); + std::vector<std::string> defaults = Config::get_list("rng/egd_path"); + + for(u32bit j = 0; j != path_list.size(); j++) + paths.push_back(path_list[j]); + for(u32bit j = 0; j != defaults.size(); j++) + paths.push_back(defaults[j]); + } + +/************************************************* +* Gather Entropy from EGD * +*************************************************/ +u32bit EGD_EntropySource::do_poll(byte output[], u32bit length, + const std::string& path) const + { + if(length > 128) + length = 128; + + sockaddr_un addr; + std::memset(&addr, 0, sizeof(addr)); + addr.sun_family = PF_LOCAL; + + if(sizeof(addr.sun_path) < path.length() + 1) + throw Exception("EGD_EntropySource: Socket path is too long"); + std::strcpy(addr.sun_path, path.c_str()); + + int fd = socket(addr.sun_family, SOCK_STREAM, 0); + if(fd == -1) return 0; + + int len = sizeof(addr.sun_family) + std::strlen(addr.sun_path) + 1; + if(connect(fd, (struct sockaddr*)&addr, len)) + { close(fd); return 0; } + + byte buffer[2]; + buffer[0] = 1; + buffer[1] = (byte)length; + + if(write(fd, buffer, 2) != 2) { close(fd); return 0; } + if(read(fd, buffer, 1) != 1) { close(fd); return 0; } + + ssize_t count = read(fd, output, buffer[0]); + + if(count == -1) { close(fd); return 0; } + + close(fd); + + return count; + } + +/************************************************* +* Gather Entropy from EGD * +*************************************************/ +u32bit EGD_EntropySource::slow_poll(byte output[], u32bit length) + { + for(u32bit j = 0; j != paths.size(); j++) + { + u32bit got = do_poll(output, length, paths[j]); + if(got) + return got; + } + return 0; + } + +} |