Overview
Comment: | FUCK THIS SHIT |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
218f1d20c2db9fe7af57802555e16f8e |
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;