Botan  1.11.15
Classes | Public Member Functions | Static Public Member Functions
Botan::Unix_EntropySource Class Reference

#include <unix_procs.h>

Inheritance diagram for Botan::Unix_EntropySource:
Botan::EntropySource

List of all members.

Classes

class  Unix_Process

Public Member Functions

std::string name () const
void poll (Entropy_Accumulator &accum) override
 Unix_EntropySource (const std::vector< std::string > &trusted_paths, size_t concurrent_processes=0)

Static Public Member Functions

static void poll_available_sources (class Entropy_Accumulator &accum)

Detailed Description

Entropy source for generic Unix. Runs various programs trying to gather data hard for a remote attacker to guess. Probably not too effective against local attackers as they can sample from the same distribution.

Definition at line 23 of file unix_procs.h.


Constructor & Destructor Documentation

Botan::Unix_EntropySource::Unix_EntropySource ( const std::vector< std::string > &  trusted_path,
size_t  proc_cnt = 0 
)
Parameters:
trusted_pathsis a list of directories that are assumed to contain only 'safe' binaries. If an attacker can write an executable to one of these directories then we will run arbitrary code.

Unix_EntropySource Constructor

Definition at line 62 of file unix_procs.cpp.

                                                        :
   m_trusted_paths(trusted_path),
   m_concurrent(concurrent_processes(proc_cnt))
   {
   }

Member Function Documentation

std::string Botan::Unix_EntropySource::name ( ) const [inline, virtual]
Returns:
name identifying this entropy source

Implements Botan::EntropySource.

Definition at line 26 of file unix_procs.h.

{ return "Unix Process Runner"; }
void Botan::Unix_EntropySource::poll ( Entropy_Accumulator accum) [override, virtual]

Perform an entropy gathering poll

Parameters:
accumis an accumulator object that will be given entropy

Implements Botan::EntropySource.

Definition at line 187 of file unix_procs.cpp.

References Botan::Entropy_Accumulator::add(), Botan::Entropy_Accumulator::get_io_buffer(), and Botan::Entropy_Accumulator::polling_goal_achieved().

   {
   // refuse to run setuid or setgid, or as root
   if((getuid() != geteuid()) || (getgid() != getegid()) || (geteuid() == 0))
      return;

   std::lock_guard<std::mutex> lock(m_mutex);

   if(m_sources.empty())
      {
      auto sources = get_default_sources();

      for(auto src : sources)
         {
         const std::string path = find_full_path_if_exists(m_trusted_paths, src[0]);
         if(path != "")
            {
            src[0] = path;
            m_sources.push_back(src);
            }
         }
      }

   if(m_sources.empty())
      return; // still empty, really nothing to try

   const size_t MS_WAIT_TIME = 32;
   const double ENTROPY_ESTIMATE = 1.0 / 1024;

   secure_vector<byte>& io_buffer = accum.get_io_buffer(4*1024); // page

   while(!accum.polling_goal_achieved())
      {
      while(m_procs.size() < m_concurrent)
         m_procs.emplace_back(Unix_Process(next_source()));

      fd_set read_set;
      FD_ZERO(&read_set);

      std::vector<int> fds;

      for(auto& proc : m_procs)
         {
         int fd = proc.fd();
         if(fd > 0)
            {
            fds.push_back(fd);
            FD_SET(fd, &read_set);
            }
         }

      if(fds.empty())
         break;

      const int max_fd = *std::max_element(fds.begin(), fds.end());

      struct ::timeval timeout;
      timeout.tv_sec = (MS_WAIT_TIME / 1000);
      timeout.tv_usec = (MS_WAIT_TIME % 1000) * 1000;

      if(::select(max_fd + 1, &read_set, nullptr, nullptr, &timeout) < 0)
         return; // or continue?

      for(auto& proc : m_procs)
         {
         int fd = proc.fd();

         if(FD_ISSET(fd, &read_set))
            {
            const ssize_t got = ::read(fd, &io_buffer[0], io_buffer.size());
            if(got > 0)
               accum.add(&io_buffer[0], got, ENTROPY_ESTIMATE);
            else
               proc.spawn(next_source());
            }
         }
      }
   }
void Botan::EntropySource::poll_available_sources ( class Entropy_Accumulator accum) [static, inherited]

Definition at line 108 of file entropy_srcs.cpp.

References Botan::Entropy_Accumulator::polling_goal_achieved().

Referenced by Botan::HMAC_RNG::reseed().

   {
   static std::vector<std::unique_ptr<EntropySource>> g_sources(get_default_entropy_sources());

   if(g_sources.empty())
      throw std::runtime_error("No entropy sources enabled at build time, poll failed");

   size_t poll_attempt = 0;

   while(!accum.polling_goal_achieved() && poll_attempt < 16)
      {
      const size_t src_idx = poll_attempt % g_sources.size();
      g_sources[src_idx]->poll(accum);
      ++poll_attempt;
      }
   }

The documentation for this class was generated from the following files: