From e73f2551feee690e9b17a077ad6131ee753cab11 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com>
Date: Wed, 25 Oct 2017 12:36:03 +0200
Subject: [PATCH] ringaccount: use base36 PIN for archive export

* Use base36 [0-9A-Z] instead of base16 (hex)
  for PIN generation.
  This increase the number of combinations from
  2^32 to ~2^41.36, an increase of ~9.36 bits.
  This increase should offset the entropy loss
  due to the optional password.
* Use random_device directly instead of the
  account (seeded) pseudo-generator because the PIN
  should have cryptographic-level randomness.

Change-Id: I00169f5d08f6794329a9e9e22b7173a0a6ef9ef4
---
 src/ringdht/ringaccount.cpp | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp
index 40c4d566c9..796b81ed04 100644
--- a/src/ringdht/ringaccount.cpp
+++ b/src/ringdht/ringaccount.cpp
@@ -981,6 +981,19 @@ RingAccount::computeKeys(const std::string& password, const std::string& pin, bo
     return {key, loc};
 }
 
+std::string
+generatePIN(size_t length = 8)
+{
+    static constexpr const char alphabet[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+    dht::crypto::random_device rd;
+    std::uniform_int_distribution<size_t> dis(0, sizeof(alphabet)-2);
+    std::string ret;
+    ret.reserve(length);
+    for (size_t i=0; i<length; i++)
+        ret.push_back(alphabet[dis(rd)]);
+    return ret;
+}
+
 void
 RingAccount::addDevice(const std::string& password)
 {
@@ -995,14 +1008,8 @@ RingAccount::addDevice(const std::string& password)
 
             a = this_->readArchive(password);
 
-            // Generate random 32bits PIN
-            std::uniform_int_distribution<uint32_t> dis;
-            auto pin = dis(this_->rand_);
-            // Manipulate PIN as hex
-            std::stringstream ss;
-            ss << std::hex << pin;
-            pin_str = ss.str();
-            std::transform(pin_str.begin(), pin_str.end(), pin_str.begin(), ::toupper);
+            // Generate random PIN
+            pin_str = generatePIN();
 
             std::tie(key, loc) = computeKeys(password, pin_str);
         } catch (const std::exception& e) {
@@ -3295,4 +3302,3 @@ RingAccount::registerDhtAddress(IceTransport& ice)
 }
 
 } // namespace ring
-
-- 
GitLab