From 80e1bd0b471c66f93c36a8731230c139ff1e2d9b Mon Sep 17 00:00:00 2001 From: cathugger Date: Wed, 6 Sep 2023 01:00:04 +0300 Subject: [PATCH] near passkeys skip/warn modes & help tweak --- main.c | 73 +++++++++++++++++++++++++---------------- worker.c | 11 ++++++- worker.h | 2 ++ worker_batch.inc.h | 2 +- worker_batch_pass.inc.h | 18 ++++++++-- 5 files changed, 72 insertions(+), 34 deletions(-) diff --git a/main.c b/main.c index 164307c..3043de2 100644 --- a/main.c +++ b/main.c @@ -96,43 +96,49 @@ static void printhelp(FILE *out,const char *progname) " %s -f FILTERFILE [OPTION]\n" "Options:\n" " -f FILTERFILE specify filter file which contains filters separated\n" - " by newlines\n" - " -D deduplicate filters\n" - " -q do not print diagnostic output to stderr\n" - " -x do not print onion names\n" - " -v print more diagnostic data\n" - " -o FILENAME output onion names to specified file (append)\n" - " -O FILENAME output onion names to specified file (overwrite)\n" - " -F include directory names in onion names output\n" - " -d DIRNAME output directory\n" + " by newlines.\n" + " -D deduplicate filters.\n" + " -q do not print diagnostic output to stderr.\n" + " -x do not print onion names.\n" + " -v print more diagnostic data.\n" + " -o FILENAME output onion names to specified file (append).\n" + " -O FILENAME output onion names to specified file (overwrite).\n" + " -F include directory names in onion names output.\n" + " -d DIRNAME output directory.\n" " -t NUMTHREADS specify number of threads to utilise\n" - " (default - try detecting CPU core count)\n" - " -j NUMTHREADS same as -t\n" - " -n NUMKEYS specify number of keys (default - 0 - unlimited)\n" - " -N NUMWORDS specify number of words per key (default - 1)\n" - " -Z deprecated, does nothing\n" - " -z deprecated, does nothing\n" - " -B use batching key generation method (current default)\n" - " -s print statistics each 10 seconds\n" - " -S SECONDS print statistics every specified amount of seconds\n" - " -T do not reset statistics counters when printing\n" + " (default - try detecting CPU core count).\n" + " -j NUMTHREADS same as -t.\n" + " -n NUMKEYS specify number of keys (default - 0 - unlimited).\n" + " -N NUMWORDS specify number of words per key (default - 1).\n" + " -Z deprecated, does nothing.\n" + " -z deprecated, does nothing.\n" + " -B use batching key generation method (current default).\n" + " -s print statistics each 10 seconds.\n" + " -S SECONDS print statistics every specified amount of seconds.\n" + " -T do not reset statistics counters when printing.\n" " -y output generated keys in YAML format instead of\n" - " dumping them to filesystem\n" + " dumping them to filesystem.\n" " -Y [FILENAME [host.onion]]\n" " parse YAML encoded input and extract key(s) to\n" - " filesystem\n" + " filesystem.\n" #ifdef PASSPHRASE - " -p PASSPHRASE use passphrase to initialize the random seed with\n" + " -p PASSPHRASE use passphrase to initialize the random seed with.\n" " -P same as -p, but takes passphrase from PASSPHRASE\n" - " environment variable\n" + " environment variable.\n" " --checkpoint filename\n" " load/save checkpoint of progress to specified file\n" - " (requires passphrase)\n" + " (requires passphrase).\n" + " --skipnear skip near passphrase keys; you probably want this\n" + " because of improved safety unless you're trying to\n" + " regenerate an old key; possible future default.\n" + " --warnnear print warning about passphrase key being near another\n" + " (safety hazard); prefer --skipnear to this unless\n" + " you're regenerating an old key.\n" #endif " --rawyaml raw (unprefixed) public/secret keys for -y/-Y\n" - " (may be useful for tor controller API)\n" - " -h, --help, --usage print help to stdout and quit\n" - " -V, --version print version information to stdout and exit\n" + " (may be useful for tor controller API).\n" + " -h, --help, --usage print help to stdout and quit.\n" + " -V, --version print version information to stdout and exit.\n" ,progname,progname); fflush(out); } @@ -332,6 +338,10 @@ int main(int argc,char **argv) else e_additional(); } + else if (!strcmp(arg,"skipnear")) + pw_skipnear = 1; + else if (!strcmp(arg,"warnnear")) + pw_warnnear = 1; #endif // PASSPHRASE else { fprintf(stderr,"unrecognised argument: --%s\n",arg); @@ -597,8 +607,13 @@ int main(int argc,char **argv) #ifdef PASSPHRASE if (deterministic) { - if (!quietflag && numneedgenerate != 1) - fprintf(stderr,"CAUTION: avoid using keys generated with same password for unrelated services, as single leaked key may help attacker to regenerate related keys.\n"); + if (!quietflag && numneedgenerate != 1 && !pw_skipnear && !pw_warnnear) + fprintf(stderr, + // 0 1 2 3 4 5 6 7 + // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 + "CAUTION: avoid using keys generated with the same password for unrelated\n" + " services, as single leaked key may help an attacker to regenerate\n" + " related keys; to silence this warning, pass --skipnear or --warnnear.\n"); if (checkpointfile) { memcpy(orig_determseed,determseed,sizeof(determseed)); // Read current checkpoint position if file exists diff --git a/worker.c b/worker.c index 0a08d27..1c954de 100644 --- a/worker.c +++ b/worker.c @@ -58,6 +58,8 @@ size_t workdirlen = 0; pthread_mutex_t determseed_mutex; u8 determseed[SEED_LEN]; +int pw_skipnear = 0; +int pw_warnnear = 0; #endif @@ -71,7 +73,7 @@ char *makesname(void) return sname; } -static void onionready(char *sname,const u8 *secret,const u8 *pubonion) +static void onionready(char *sname,const u8 *secret,const u8 *pubonion,int warnnear) { if (endwork) return; @@ -122,6 +124,13 @@ static void onionready(char *sname,const u8 *secret,const u8 *pubonion) } if (fout) { pthread_mutex_lock(&fout_mutex); +#ifdef PASSPHRASE + const char * const pwarn = " warn:near\n"; + if (warnnear) + strcpy(&sname[onionendpos],pwarn); + const size_t oprintlen = printlen; + const size_t printlen = oprintlen + (warnnear ? strlen(pwarn)-1 : 0); +#endif fwrite(&sname[printstartpos],printlen,1,fout); fflush(fout); pthread_mutex_unlock(&fout_mutex); diff --git a/worker.h b/worker.h index 2c30831..547b72a 100644 --- a/worker.h +++ b/worker.h @@ -33,6 +33,8 @@ VEC_STRUCT(statsvec,struct statstruct); #ifdef PASSPHRASE extern pthread_mutex_t determseed_mutex; extern u8 determseed[SEED_LEN]; +extern int pw_skipnear; +extern int pw_warnnear; #endif extern void worker_init(void); diff --git a/worker_batch.inc.h b/worker_batch.inc.h index 7eb5cd6..7bf778d 100644 --- a/worker_batch.inc.h +++ b/worker_batch.inc.h @@ -102,7 +102,7 @@ initseed: pk[PUBLIC_LEN + 2] = 0x03; // full name strcpy(base32_to(&sname[direndpos],pk,PUBONION_LEN),".onion"); - onionready(sname,secret,pubonion.raw); + onionready(sname,secret,pubonion.raw,0); pk[PUBLIC_LEN] = 0; // what is this for? // don't reuse same seed goto initseed; diff --git a/worker_batch_pass.inc.h b/worker_batch_pass.inc.h index 0fa49ff..3d31174 100644 --- a/worker_batch_pass.inc.h +++ b/worker_batch_pass.inc.h @@ -38,17 +38,21 @@ void *CRYPTO_NAMESPACE(worker_batch_pass)(void *task) sname = makesname(); + int seednear; + initseed: #ifdef STATISTICS ++st->numrestart.v; #endif + seednear = 0; + pthread_mutex_lock(&determseed_mutex); for (int i = 0; i < SEED_LEN; i++) if (++determseed[i]) break; - memcpy(seed, determseed, SEED_LEN); + memcpy(seed,determseed,SEED_LEN); pthread_mutex_unlock(&determseed_mutex); ed25519_seckey_expand(sk,seed); @@ -112,8 +116,12 @@ initseed: pk[PUBLIC_LEN + 2] = 0x03; // full name strcpy(base32_to(&sname[direndpos],pk,PUBONION_LEN),".onion"); - onionready(sname,secret,pubonion.raw); + onionready(sname,secret,pubonion.raw,seednear && pw_warnnear); pk[PUBLIC_LEN] = 0; // what is this for? + + if (pw_skipnear) + goto initseed; + seednear = 1; }); next: ; @@ -180,8 +188,12 @@ initseed: pk[PUBLIC_LEN + 2] = 0x03; // full name strcpy(base32_to(&sname[direndpos],pk,PUBONION_LEN),".onion"); - onionready(sname,secret,pubonion.raw); + onionready(sname,secret,pubonion.raw,seednear && pw_warnnear); pk[PUBLIC_LEN] = 0; // what is this for? + + if (pw_skipnear) + goto initseed; + seednear = 1; }); next2: ;