util  Diff

Differences From Artifact [f4297483ea]:

To Artifact [22f71ce9d0]:


   339    339   	} else {
   340    340   		printf("path is %s", dbpath);
   341    341   		db = open(dbpath, flags, 0600);
   342    342   	}
   343    343   
   344    344   	return db;
   345    345   }
          346  +
          347  +void bytedump(uint8_t* bytes, size_t sz) {
          348  +	for (size_t i = 0; i < sz; ++i) {
          349  +		char tpl[] ="\x1b[35m \x1b[m";
          350  +		char* c = tpl + 5;
          351  +		*c = bytes[i];
          352  +		if (*c < ' ' || *c > '~') *c='.', write(2, tpl, sz(tpl));
          353  +		else write(2, c, 1);
          354  +	}
          355  +}
          356  +void hexdump(uint8_t* bytes, size_t sz) {
          357  +	if(!_g_debug_msgs) return;
          358  +	alert(a_debug, "printing hex dump");
          359  +	uint8_t* st = bytes;
          360  +	for (size_t i = 0; i < sz; ++i) {
          361  +		char hex[5] = "    ";
          362  +		kitoa(16, bytes[i], hex, hex + 2, NULL, true);
          363  +		write(2, hex, 4);
          364  +		if(!((i+1)%8)) {
          365  +			write(2, _str("│ "));
          366  +			bytedump(st, 8);
          367  +			write(2, "\n", 1);
          368  +			st += 8;
          369  +		} else if (i == sz - 1) {
          370  +			write(2, _str("│ "));
          371  +			bytedump(st, (bytes + sz) - st);
          372  +			write(2, "\n", 1);
          373  +		}
          374  +	}
          375  +}
   346    376   
   347    377   int
   348    378   kpw(int argc, const char** argv) {
   349    379   	if (argc == 0) return bad_insane;
   350    380   	_g_binary_name = argv[0];
   351    381   
   352    382   	enum genmode
................................................................................
   454    484   					alert(a_debug, "converting length parameter to integer");
   455    485   					bad e = katoi(10, prm, &len);
   456    486   					if (e != ok) return bad_num;
   457    487   				} else alert(a_debug, "using default password length"),
   458    488   				       len = default_pw_len;
   459    489   
   460    490   				alert(a_debug, "generating new password");
   461         -				mkpw(mode, pw, len);
          491  +				if (mkpw(mode, pw, len) == bad_entropy) return bad_entropy;
   462    492   				if (print || !tty_out) {
   463    493   					write(1, pw, len);
   464    494   					if(tty_out) write(1, "\n", 1);
   465    495   				}
   466    496   				pwlen = len;
   467    497   			}
   468    498   			if (copy_pw) copy(pw, pwlen);
   469         -			alert(a_debug, "enciphering password");
          499  +			alert(a_debug, "encoding database entry");
          500  +			uint8_t acctlen = strlen(acct);
          501  +			uint8_t plaintext[1 + acctlen +
          502  +			                  1 + pwlen];
          503  +			plaintext[0] = acctlen;
          504  +			strncpy(plaintext + 1, acct, acctlen);
          505  +			plaintext[1 + acctlen] = pwlen;
          506  +			strncpy(plaintext + acctlen + 2, pw, pwlen);
          507  +			hexdump(plaintext, sz(plaintext));
   470    508   
          509  +			alert(a_debug, "enciphering database entry");
          510  +
          511  +			uint8_t ciphertext[sz(plaintext) + crypto_box_SEALBYTES];
          512  +			crypto_box_seal(ciphertext, plaintext, sz(plaintext), key);
          513  +			hexdump(ciphertext, sz(ciphertext));
          514  +
          515  +			alert(a_debug, "writing ciphertext to db");
          516  +			uint8_t ciphertext_len = sz(ciphertext);
          517  +			write(db, &ciphertext_len, 1);
          518  +			write(db, &ciphertext, ciphertext_len);
          519  +			
          520  +			close(db);
   471    521   			break;
   472    522   		}
   473    523   
   474    524   		case delpw:{ /* kpw -d <acct> */
   475    525   			break;
   476    526   		}
   477    527   
   478    528   		case lspw: { /* kpw -t[p] [<prefix>] */
          529  +			alert(a_debug, "opening database for reading");
          530  +			int db = dbopen(O_RDONLY);
          531  +			if (db == -1) return bad_db_load;
          532  +			password dbpw; size_t pwlen;
          533  +			bad e = pwread(!print, dbpw, &pwlen,_str("database key: "));
          534  +
          535  +			uint8_t salt     [crypto_pwhash_SALTBYTES],
          536  +			        key      [db_privkey_len],
          537  +			        priv_enc [db_privkey_len],
          538  +			        priv     [db_privkey_len],
          539  +					pub      [db_pubkey_len];
          540  +			uint8_t salt_enc [crypto_box_SEALBYTES + sz(salt)],
          541  +			        salt_dec [sz(salt)];
          542  +			bzero(salt_dec, sz(salt_dec));
          543  +
          544  +			alert(a_debug, "loading public key");
          545  +			ssize_t sr = read(db, pub, sz(pub));
          546  +			if (sr != sz(pub)) return bad_db_corrupt;
          547  +			hexdump(pub, sz(pub));
          548  +
          549  +			alert(a_debug, "loading password salt");
          550  +			sr = read(db, salt, sz(salt));
          551  +			if (sr != sz(salt)) return bad_db_corrupt;
          552  +			hexdump(salt, sz(salt));
          553  +			
          554  +			alert(a_debug, "deriving secret");
          555  +			if(crypto_pwhash(key, sz(key), dbpw, pwlen, salt,
          556  +					crypto_pwhash_OPSLIMIT_INTERACTIVE,
          557  +					crypto_pwhash_MEMLIMIT_INTERACTIVE,
          558  +					crypto_pwhash_ALG_DEFAULT) != 0) {
          559  +				return bad_mem;
          560  +			}
          561  +			hexdump(key, sz(key));
          562  +
          563  +			alert(a_debug, "loading encrypted private key");
          564  +			read(db, priv_enc, sz(priv_enc));
          565  +			hexdump(priv_enc, sz(priv_enc));
          566  +
          567  +			alert(a_debug, "decrypting private key");
          568  +			for (size_t i = 0; i < sz(key); ++i) {
          569  +				priv[i] = priv_enc[i] ^ key[i];
          570  +			}
          571  +			hexdump(priv, sz(priv));
          572  +
          573  +			alert(a_debug, "loading verification hash");
          574  +			read(db, salt_enc, sz(salt_enc));
          575  +			hexdump(salt_enc, sz(salt_enc));
          576  +
          577  +			alert(a_debug, "decrypting verification hash");
          578  +			hexdump(pub, sz(pub));
          579  +			hexdump(priv, sz(priv));
          580  +			printf("sz salt_enc = %zu\n / crypto_box bytes = %zu", sz(salt_enc), crypto_box_SEALBYTES);
          581  +			int r = crypto_box_seal_open(salt_dec, salt_enc,
          582  +					sz(salt_enc), pub, priv);
          583  +			printf("result code: %d\n",r);
          584  +			hexdump(salt_dec, sz(salt_dec));
   479    585   			break;
   480    586   		}
   481    587   
   482    588   		case createdb: { /* kpw -C [<db>] */
   483    589   			alert(a_debug, "creating new database");
   484    590   			if (clobber)
   485    591   				alert(a_warn, "will clobber any existing database");
................................................................................
   504    610   			 * prompt  the user for a secret  passphrase with
   505    611   			 * which to encrypt the private key with.
   506    612   			 */
   507    613   
   508    614   			alert(a_notice, "database keypair generated, encrypting");
   509    615   			password dbpw;
   510    616   			size_t pwlen;
   511         -			bad e = pwread(!print, dbpw, &pwlen, _str("- database passphrase: "));
          617  +			bad e = pwread(!print, dbpw, &pwlen, _str("- new database key: "));
   512    618   			if (e != ok) return e;
   513    619   			if (!print && isatty(0)) {
   514    620   				password dbpw_conf;
   515    621   				e = pwread(!print, dbpw_conf, NULL, _str("- confirm: "));
   516    622   				if (e != ok) return e;
   517    623   
   518    624   				if(strcmp(dbpw,dbpw_conf) != 0)
................................................................................
   519    625   					return bad_pw_match;
   520    626   			}
   521    627   
   522    628   			uint8_t salt[crypto_pwhash_SALTBYTES],
   523    629   			         key[db_privkey_len];
   524    630   			uint8_t salt_enc[crypto_box_SEALBYTES + sz(salt)];
   525    631   
          632  +			alert(a_debug, "generating salt");
   526    633   			if (syscall(SYS_getrandom, salt, sz(salt), 0) == -1)
   527    634   				return bad_entropy;
          635  +			hexdump(salt, sz(salt));
   528    636   
          637  +			alert(a_debug, "hashing database keyphrase");
   529    638   			if(crypto_pwhash(key, sz(key), dbpw, pwlen, salt,
   530    639   					crypto_pwhash_OPSLIMIT_INTERACTIVE,
   531    640   					crypto_pwhash_MEMLIMIT_INTERACTIVE,
   532    641   					crypto_pwhash_ALG_DEFAULT) != 0) {
   533    642   				return bad_mem;
   534    643   			}
   535    644   
          645  +			alert(a_debug, "encrypting private key");
          646  +			hexdump(priv, sz(priv));
   536    647   			for (size_t i = 0; i < sz(key); ++i) {
   537    648   				priv_enc[i] = priv[i] ^ key[i];
   538    649   			}
          650  +			alert(a_debug, "private key encrypted");
          651  +			hexdump(priv_enc, sz(priv_enc));
   539    652   
          653  +			alert(a_debug, "encrypting salt");
   540    654   			crypto_box_seal(salt_enc, salt, sz(salt), priv);
          655  +			hexdump(salt_enc, sz(salt_enc));
   541    656   
   542    657   			/* we have everything we need. now we create the
   543    658   			 * file, failing  if it already exists so as not
   544    659   			 * to clobber anyone's passwords.
   545    660   			 */
          661  +			alert(a_debug, "creating new database on disk");
   546    662   			int db;
   547    663   			const int flags = O_CREAT | O_WRONLY |
   548    664   				(clobber ? O_TRUNC : O_EXCL);
   549    665   			if(param == 0)
   550    666   				db = dbopen(flags);
   551    667   			else if (param == 1)
   552    668   				db = open(params[0], flags, 0600);
................................................................................
   554    670   
   555    671   			if (db == -1) return bad_db_create;
   556    672   
   557    673   			/* the file is safely created; all that's left to
   558    674   			 * do is write out the header and then we can call
   559    675   			 * it a day.
   560    676   			 */
          677  +			alert(a_debug, "writing public key");
          678  +			hexdump(pub, sz(pub));
          679  +
   561    680   			write(db, pub, sz(pub));
   562    681   			write(db, salt, sz(salt));
   563    682   			write(db, priv_enc, sz(priv_enc));
   564    683   			write(db, salt_enc, sz(salt_enc));
   565    684   			close(db);
   566    685   
   567    686   			alert(a_debug, "database created");
   568    687   			break;
   569    688   		}
   570    689   	}
   571    690   
   572         -	
   573         -
   574         -	/* char buf[len+1]; */
   575         -	/* *buf = 0; */
   576         -	/* mkpw(mode,buf,len); */
   577         -	/* write(1, buf, len + 1); */
   578         -
   579    691   #	ifdef _CLIPBOARD
   580    692   		if (copy_pw) {
   581    693   			/* copy(buf,len); */
   582    694   		}
   583    695   #	endif
   584    696   	
   585    697   	return ok;