aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--agent/call-pinentry.c21
-rw-r--r--doc/gpg.texi7
-rw-r--r--g10/gpg.c24
3 files changed, 38 insertions, 14 deletions
diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
index 711758efc..c6c52be74 100644
--- a/agent/call-pinentry.c
+++ b/agent/call-pinentry.c
@@ -57,7 +57,9 @@
* passphrase will be rendered as zbase32 which results for 150 bits
* in a string of 30 characters. That fits nicely into the 5
* character blocking which pinentry can do. 128 bits would actually
- * be sufficient but can't be formatted nicely. */
+ * be sufficient but can't be formatted nicely. Please do not change
+ * this value because pattern check files may let such passwords
+ * always pass. */
#define DEFAULT_GENPIN_BITS 150
/* The assuan context of the current pinentry. */
@@ -844,21 +846,20 @@ estimate_passphrase_quality (const char *pw)
/* Generate a random passphrase in zBase32 encoding (RFC-6189) to be
- * used by Pinentry to suggest a passphrase. */
+ * used by Pinentry to suggest a passphrase. Note that we have the
+ * same algorithm in gpg.c for --gen-random at level 30. It is
+ * important that we always output exactly 30 characters to match the
+ * special exception we have in the pattern file for symmetric
+ * encryption. */
static char *
generate_pin (void)
{
- unsigned int nbits = opt.min_passphrase_len * 8;
- size_t nbytes;
+ unsigned int nbits = DEFAULT_GENPIN_BITS;
+ size_t nbytes = nbytes = (nbits + 7) / 8;
void *rand;
char *generated;
- if (nbits < 128)
- nbits = DEFAULT_GENPIN_BITS;
-
- nbytes = (nbits + 7) / 8;
-
- rand = gcry_random_bytes_secure (nbytes, GCRY_STRONG_RANDOM);
+ rand = gcry_random_bytes_secure (nbytes, GCRY_STRONG_RANDOM);
if (!rand)
{
log_error ("failed to generate random pin\n");
diff --git a/doc/gpg.texi b/doc/gpg.texi
index f6c445658..08de40b0a 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -610,13 +610,14 @@ Print message digest of algorithm @var{algo} for all given files or STDIN.
With the second form (or a deprecated "*" for @var{algo}) digests for all
available algorithms are printed.
-@item --gen-random @var{0|1|2} @var{count}
+@item --gen-random @var{0|1|2|16|30} @var{count}
@opindex gen-random
Emit @var{count} random bytes of the given quality level 0, 1 or 2. If
@var{count} is not given or zero, an endless sequence of random bytes
will be emitted. If used with @option{--armor} the output will be
-base64 encoded. PLEASE, don't use this command unless you know what
-you are doing; it may remove precious entropy from the system!
+base64 encoded. The special level 16 uses a quality level of 1 and
+outpust end endless stream of hex-encoded octets. The special level
+30 outputs random as 30 zBase-32 characters.
@item --gen-prime @var{mode} @var{bits}
@opindex gen-prime
diff --git a/g10/gpg.c b/g10/gpg.c
index 466a48d9d..397f4cc87 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -64,6 +64,7 @@
#include "objcache.h"
#include "../common/init.h"
#include "../common/mbox-util.h"
+#include "../common/zb32.h"
#include "../common/shareddefs.h"
#include "../common/compliance.h"
#include "../common/comopt.h"
@@ -5068,8 +5069,29 @@ main (int argc, char **argv)
if (hexhack)
level = 1;
+ /* Level 30 uses the same algorithm as our magic wand in
+ * pinentry/gpg-agent. */
+ if (level == 30)
+ {
+ unsigned int nbits = 150;
+ size_t nbytes = (nbits + 7) / 8;
+ void *rand;
+ char *generated;
+
+ rand = gcry_random_bytes_secure (nbytes, GCRY_STRONG_RANDOM);
+ if (!rand)
+ log_fatal ("failed to generate random password\n");
+
+ generated = zb32_encode (rand, nbits);
+ gcry_free (rand);
+ es_fputs (generated, es_stdout);
+ es_putc ('\n', es_stdout);
+ xfree (generated);
+ break;
+ }
+
if (argc < 1 || argc > 2 || level < 0 || level > 2 || count < 0)
- wrong_args ("--gen-random 0|1|2 [count]");
+ wrong_args ("--gen-random 0|1|2|16|30 [count]");
while (endless || count)
{