util  Check-in [218f1d20c2]

Overview
Comment:FUCK THIS SHIT
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 218f1d20c2db9fe7af57802555e16f8eefe813d879e0acbd734ef2b9bf682cab
User & Date: lexi on 2019-08-15 11:24:16
Other Links: manifest | tags
Context
2019-08-15
12:31
my monster liiiiives check-in: 5089ec59d3 user: lexi tags: trunk
11:24
FUCK THIS SHIT check-in: 218f1d20c2 user: lexi tags: trunk
08:34
updates check-in: c2ffe127f3 user: lexi tags: trunk
Changes

Modified kpw.d/db.md from [f52a921e08] to [5982f7fb3c].

     8      8    4. encrypt(private key, password salt) [for pw verification]
     9      9    5. record *
    10     10   
    11     11   each record takes the form of
    12     12   
    13     13    1. account name length (1 byte)
    14     14    2. account name
    15         - 3. password length (4 bytes)
           15  + 3. password length (1 byte)
    16     16    4. password
    17     17   
    18     18   records are added simply by encrypting them with the public key and appending them to the end of the file. thus, adding a new password does not require the decryption password.

Modified kpw.d/kpw.c from [f4297483ea] to [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;