diff --git a/lib/entropy.cpp b/lib/entropy.cpp index e4c26102..14cfa754 100644 --- a/lib/entropy.cpp +++ b/lib/entropy.cpp @@ -27,6 +27,38 @@ #define O_NONBLOCK 0 #endif +/* Entropy sources for XCA + * + * Entropy is a very important topic for key generation. + * + * XCA uses the following sources for entropy: + * + * 1) During startup + * RAND_poll() + * The OpenSSL seeding mechanism. + * It uses /dev/urandom where possible and the + * Screen content on Windows. + * + * If "/dev/random" exists, it will be used for additional + * 256bit entropy. Same is true for "/dev/hwrng" + * + * 2) Before any key or parameter generation a "reseeding" + * is done. Some say reseeding is not neccessary, but + * all say it does not harm. + * + * Entropy by Mouse and keyboard events + * main.cpp: bool XCA_application::eventFilter() + * 256bit from /dev/urandom (unix/Mac) + * + * 3) A .rnd state file in the XCA application directory + * is written on exit and read on startup. + * After reading it, the file will be erased to avoid replays. + * + * 4) When managing a token that supports C_GenerateRandom + * and C_SeedRandom, XCA will seed the token and in return + * seed himself from the token. + */ + #undef DEBUG_ENTROPY #define pool_siz (sizeof(pool)/sizeof(pool[0])) @@ -61,14 +93,8 @@ void Entropy::seed_rng() RAND_seed(pool, pool_pos); seed_strength += pool_pos; -#if defined(Q_OS_WIN32) - if (seed_strength < 16) { - RAND_poll(); - seed_strength += 8; - } -#else - random_from_file("/dev/random", 64); - random_from_file("/dev/hwrng", 64); +#if !defined(Q_OS_WIN32) + random_from_file("/dev/urandom", 32); #endif #ifdef DEBUG_ENTROPY fprintf(stderr, "Seeding %d bytes:", pool_pos); @@ -82,13 +108,11 @@ void Entropy::seed_rng() int Entropy::random_from_file(QString fname, unsigned amount, int weakness) { char buf[256]; - const char *file; int fd, sum; - QByteArray ba; - - ba = filename2bytearray(fname); - file = ba.constData(); + QByteArray ba = filename2bytearray(fname); + const char *file = ba.constData(); + /* OpenSSL: RAND_load_file() is blocking */ fd = open(file, O_RDONLY | O_NONBLOCK); if (fd == -1) @@ -131,20 +155,20 @@ Entropy::Entropy() rnd = getUserSettingsDir() + QDir::separator() + ".rnd"; random_from_file(rnd, 1024, 128); QFile::remove(rnd); // don't use it again + + RAND_poll(); + seed_strength += 8; + +#if !defined(Q_OS_WIN32) + random_from_file("/dev/random", 32); + random_from_file("/dev/hwrng", 32); +#endif } Entropy::~Entropy() { - QFile f(rnd); - - if (f.open(QIODevice::ReadWrite)) { - unsigned char buf[1024]; - seed_rng(); - f.setPermissions(QFile::ReadOwner|QFile::WriteOwner); - RAND_bytes(buf, sizeof buf); - f.write((char*)buf, sizeof buf); - f.close(); - } + QByteArray ba = filename2bytearray(rnd); + RAND_write_file(ba.constData()); #ifdef DEBUG_ENTROPY fprintf(stderr, "Seed strength: %d\n", seed_strength); #endif diff --git a/lib/main.cpp b/lib/main.cpp index 79e6d0e8..fa401396 100644 --- a/lib/main.cpp +++ b/lib/main.cpp @@ -303,6 +303,7 @@ int main( int argc, char *argv[] ) { int ret = 0, pkictr; MainWindow *mw; + QDir d; #if defined(Q_OS_WIN32) SetUnhandledExceptionFilter(w32_segfault); @@ -313,6 +314,7 @@ int main( int argc, char *argv[] ) if (QString(argv[1]) == "extract") { return main_extract(argc, argv); } + d.mkpath(getUserSettingsDir()); XCA_application a(argc, argv); mw = new MainWindow(NULL); try { diff --git a/lib/openssl_compat.h b/lib/openssl_compat.h index 558410aa..d3c371ff 100644 --- a/lib/openssl_compat.h +++ b/lib/openssl_compat.h @@ -19,7 +19,6 @@ #include #define RAND_bytes(buf, size) RAND_pseudo_bytes((buf), (size)) -#define RAND_poll() RAND_screen() #define X509_get0_extensions(cert) ((cert)->cert_info->extensions) #define X509_get_signature_nid(cert) OBJ_obj2nid((cert)->sig_alg->algorithm)