int main(void) { int i; static char str[256]; unsigned char *md5; unsigned int seed; readpass(str, 256); // the time used to type the pass is entropy srand(time(NULL)); seed = rand(); md5 = chash_double(str, seed); for (i = 0; i < 20; i++) printf("%02x", md5[i]); printf("\n"); free(md5); return 0; }
int main(int argc, char *argv[]) { int n, i, cnt = 1, pass = 0, hexmode = 0; char passwd[SKEY_MAX_PW_LEN+1], key[SKEY_BINKEY_SIZE]; char buf[33], *seed, *slash; /* If we were called as otp-METHOD, set algorithm based on that */ if ((slash = strrchr(argv[0], '/'))) slash++; else slash = argv[0]; if (strncmp(slash, "otp-", 4) == 0) { slash += 4; if (skey_set_algorithm(slash) == NULL) errx(1, "Unknown hash algorithm %s", slash); } for (i = 1; i < argc && argv[i][0] == '-' && strcmp(argv[i], "--");) { if (argv[i][2] == '\0') { /* Single character switch */ switch (argv[i][1]) { case 'n': if (++i == argc) usage(argv[0]); cnt = atoi(argv[i]); break; case 'p': if (++i == argc) usage(argv[0]); if (strlcpy(passwd, argv[i], sizeof(passwd)) >= sizeof(passwd)) errx(1, "Password too long"); pass = 1; break; case 'x': hexmode = 1; break; default: usage(argv[0]); } } else { /* Multi character switches are hash types */ if (skey_set_algorithm(&argv[i][1]) == NULL) { warnx("Unknown hash algorithm %s", &argv[i][1]); usage(argv[0]); } } i++; } if (argc > i + 2) usage(argv[0]); /* Could be in the form <number>/<seed> */ if (argc <= i + 1) { /* look for / in it */ if (argc <= i) usage(argv[0]); slash = strchr(argv[i], '/'); if (slash == NULL) usage(argv[0]); *slash++ = '\0'; seed = slash; if ((n = atoi(argv[i])) < 0) { warnx("%d not positive", n); usage(argv[0]); } else if (n > SKEY_MAX_SEQ) { warnx("%d is larger than max (%d)", n, SKEY_MAX_SEQ); usage(argv[0]); } } else { if ((n = atoi(argv[i])) < 0) { warnx("%d not positive", n); usage(argv[0]); } else if (n > SKEY_MAX_SEQ) { warnx("%d is larger than max (%d)", n, SKEY_MAX_SEQ); usage(argv[0]); } seed = argv[++i]; } /* Get user's secret passphrase */ if (!pass) { fputs("Reminder - Do not use this program while" " logged in via telnet.\n", stderr); (void)fputs("Enter secret passphrase: ", stderr); readpass(passwd, sizeof(passwd)); if (passwd[0] == '\0') exit(1); } /* Crunch seed and passphrase into starting key */ if (keycrunch(key, seed, passwd) != 0) errx(1, "key crunch failed"); if (cnt == 1) { while (n-- != 0) f(key); (void)puts(hexmode ? put8(buf, key) : btoe(buf, key)); } else { for (i = 0; i <= n - cnt; i++) f(key); for (; i <= n; i++) { if (hexmode) (void)printf("%d: %s\n", i, put8(buf, key)); else (void)printf("%d: %-29s\n", i, btoe(buf, key)); f(key); } } exit(0); }
int main(int argc, char *argv[]) { FILE * infile; FILE * outfile; int dec = 0; size_t maxmem = 0; double maxmemfrac = 0.5; double maxtime = 300.0; const char * ch; char * passwd; int rc; int verbose = 0; WARNP_INIT; /* We should have "enc" or "dec" first. */ if (argc < 2) usage(); if (strcmp(argv[1], "enc") == 0) { maxmem = 0; maxmemfrac = 0.125; maxtime = 5.0; } else if (strcmp(argv[1], "dec") == 0) { dec = 1; } else usage(); argc--; argv++; /* Parse arguments. */ while ((ch = GETOPT(argc, argv)) != NULL) { GETOPT_SWITCH(ch) { GETOPT_OPTARG("-M"): maxmem = strtoumax(optarg, NULL, 0); break; GETOPT_OPTARG("-m"): maxmemfrac = strtod(optarg, NULL); break; GETOPT_OPTARG("-t"): maxtime = strtod(optarg, NULL); break; GETOPT_OPT("-v"): verbose = 1; break; GETOPT_MISSING_ARG: warn0("Missing argument to %s\n", ch); /* FALLTHROUGH */ GETOPT_DEFAULT: usage(); } } argc -= optind; argv += optind; /* We must have one or two parameters left. */ if ((argc < 1) || (argc > 2)) usage(); /* If the input isn't stdin, open the file. */ if (strcmp(argv[0], "-")) { if ((infile = fopen(argv[0], "rb")) == NULL) { warnp("Cannot open input file: %s", argv[0]); exit(1); } } else { infile = stdin; } /* If we have an output file, open it. */ if (argc > 1) { if ((outfile = fopen(argv[1], "wb")) == NULL) { warnp("Cannot open output file: %s", argv[1]); exit(1); } } else { outfile = stdout; } /* Prompt for a password. */ if (readpass(&passwd, "Please enter passphrase", dec ? NULL : "Please confirm passphrase", 1)) exit(1); /* Encrypt or decrypt. */ if (dec) rc = scryptdec_file(infile, outfile, (uint8_t *)passwd, strlen(passwd), maxmem, maxmemfrac, maxtime, verbose); else rc = scryptenc_file(infile, outfile, (uint8_t *)passwd, strlen(passwd), maxmem, maxmemfrac, maxtime, verbose); /* Zero and free the password. */ insecure_memzero(passwd, strlen(passwd)); free(passwd); /* Close any files we opened. */ if (infile != stdin) fclose(infile); if (outfile != stdout) fclose(outfile); /* If we failed, print the right error message and exit. */ if (rc != 0) { switch (rc) { case 1: warnp("Error determining amount of available memory"); break; case 2: warnp("Error reading clocks"); break; case 3: warnp("Error computing derived key"); break; case 4: warnp("Error reading salt"); break; case 5: warnp("OpenSSL error"); break; case 6: warnp("Error allocating memory"); break; case 7: warn0("Input is not valid scrypt-encrypted block"); break; case 8: warn0("Unrecognized scrypt format version"); break; case 9: warn0("Decrypting file would require too much memory"); break; case 10: warn0("Decrypting file would take too much CPU time"); break; case 11: warn0("Passphrase is incorrect"); break; case 12: warnp("Error writing file: %s", (argc > 1) ? argv[1] : "standard output"); break; case 13: warnp("Error reading file: %s", argv[0]); break; } exit(1); } return (0); }
int main(int argc, char **argv) { struct register_internal C; const char * keyfilename; FILE * keyfile; NETPACKET_CONNECTION * NPC; int passphrased; uint64_t maxmem; double maxtime; char * passphrase; WARNP_INIT; /* We have no username, machine name, or key filename yet. */ C.user = C.name = NULL; keyfilename = NULL; /* * So far we're not using a passphrase, have unlimited RAM, and allow * up to 1 second of CPU time. */ passphrased = 0; maxmem = 0; maxtime = 1.0; /* Parse arguments. */ while (--argc > 0) { argv++; if (strcmp(argv[0], "--user") == 0) { if ((C.user != NULL) || (argc < 2)) usage(); C.user = argv[1]; argv++; argc--; } else if (strcmp(argv[0], "--machine") == 0) { if ((C.name != NULL) || (argc < 2)) usage(); C.name = argv[1]; argv++; argc--; } else if (strcmp(argv[0], "--keyfile") == 0) { if ((keyfilename != NULL) || (argc < 2)) usage(); keyfilename = argv[1]; argv++; argc--; } else if (strcmp(argv[0], "--passphrase-mem") == 0) { if ((maxmem != 0) || (argc < 2)) usage(); if (humansize_parse(argv[1], &maxmem)) { warnp("Cannot parse --passphrase-mem" " argument: %s", argv[1]); exit(1); } argv++; argc--; } else if (strcmp(argv[0], "--passphrase-time") == 0) { if ((maxtime != 1.0) || (argc < 2)) usage(); maxtime = strtod(argv[1], NULL); if ((maxtime < 0.05) || (maxtime > 86400)) { warn0("Invalid --passphrase-time argument: %s", argv[1]); exit(1); } argv++; argc--; } else if (strcmp(argv[0], "--passphrased") == 0) { passphrased = 1; } else { usage(); } } /* We must have a user name, machine name, and key file specified. */ if ((C.user == NULL) || (C.name == NULL) || (keyfilename == NULL)) usage(); /* * It doesn't make sense to specify --passphrase-mem or * --passphrase-time if we're not using a passphrase. */ if (((maxmem != 0) || (maxtime != 1.0)) && (passphrased == 0)) usage(); /* Sanity-check the user name. */ if (strlen(C.user) > 255) { fprintf(stderr, "User name too long: %s\n", C.user); exit(1); } if (strlen(C.user) == 0) { fprintf(stderr, "User name must be non-empty\n"); exit(1); } /* Sanity-check the machine name. */ if (strlen(C.name) > 255) { fprintf(stderr, "Machine name too long: %s\n", C.name); exit(1); } if (strlen(C.name) == 0) { fprintf(stderr, "Machine name must be non-empty\n"); exit(1); } /* Get a password. */ if (readpass(&C.passwd, "Enter tarsnap account password", NULL, 0)) { warnp("Error reading password"); exit(1); } /* * Create key file -- we do this now rather than later so that we * avoid registering with the server if we won't be able to create * the key file later. */ if ((keyfile = keyfile_write_open(keyfilename)) == NULL) { warnp("Cannot create %s", keyfilename); exit(1); } /* Initialize key cache. */ if (crypto_keys_init()) { warnp("Key cache initialization failed"); goto err1; } /* Generate keys. */ if (crypto_keys_generate(CRYPTO_KEYMASK_USER)) { warnp("Error generating keys"); goto err1; } /* * We're not done, haven't answered a challenge, and don't have a * machine number. */ C.done = 0; C.donechallenge = 0; C.machinenum = (uint64_t)(-1); /* Open netpacket connection. */ if ((NPC = netpacket_open(USERAGENT)) == NULL) goto err2; /* Ask the netpacket layer to send a request and get a response. */ if (netpacket_op(NPC, callback_register_send, &C)) goto err2; /* Run event loop until an error occurs or we're done. */ if (network_spin(&C.done)) goto err2; /* Close netpacket connection. */ if (netpacket_close(NPC)) goto err2; /* * If we didn't respond to a challenge, the server's response must * have been a "no such user" error. */ if ((C.donechallenge == 0) && (C.status != 1)) { netproto_printerr(NETPROTO_STATUS_PROTERR); goto err1; } /* The machine number should be -1 iff the status is nonzero. */ if (((C.machinenum == (uint64_t)(-1)) && (C.status == 0)) || ((C.machinenum != (uint64_t)(-1)) && (C.status != 0))) { netproto_printerr(NETPROTO_STATUS_PROTERR); goto err1; } /* Parse status returned by server. */ switch (C.status) { case 0: /* Success! */ break; case 1: warn0("No such user: %s", C.user); break; case 2: warn0("Incorrect password"); break; case 3: warn0("Cannot register with server: " "Account balance for user %s is not positive", C.user); break; default: netproto_printerr(NETPROTO_STATUS_PROTERR); goto err2; } /* Shut down the network event loop. */ network_fini(); /* Exit with a code of 1 if we couldn't register. */ if (C.machinenum == (uint64_t)(-1)) goto err1; /* If the user wants to passphrase the keyfile, get the passphrase. */ if (passphrased != 0) { if (readpass(&passphrase, "Please enter passphrase for keyfile encryption", "Please confirm passphrase for keyfile encryption", 1)) { warnp("Error reading password"); goto err1; } } else { passphrase = NULL; } /* Write keys to file. */ if (keyfile_write_file(keyfile, C.machinenum, CRYPTO_KEYMASK_USER, passphrase, maxmem, maxtime)) goto err1; /* Close the key file. */ if (fclose(keyfile)) { warnp("Error closing key file"); goto err1; } /* Success! */ return (0); err2: warnp("Error registering with server"); err1: unlink(keyfilename); exit(1); }
static char * prompt_password(const char *prompt, int with_echo) { static char nostring[1] = ""; static char *return_value; volatile int tty_opened; static FILE *ifp, *ofp; volatile int is_tty; #ifdef HAVE_SIGACTION struct sigaction old_sigact; #else RETSIGTYPE (*old_signal)(); #endif TERMIO old_modes; int max_asterisks = getdef_num("GETPASS_ASTERISKS", -1); /* * set a flag so the SIGINT signal can be re-sent if it * is caught */ sig_caught = 0; return_value = NULL; tty_opened = 0; /* * if /dev/tty can't be opened, getpass() needs to read * from stdin and write to stderr instead. */ if (!(ifp = fopen("/dev/tty", "r+"))) { ifp = stdin; ofp = stderr; } else { ofp = ifp; tty_opened = 1; } setbuf(ifp, (char *) 0); /* * the current tty modes must be saved so they can be * restored later on. echo will be turned off, except * for the newline character */ is_tty = 1; if (GTTY(fileno(ifp), &old_modes)) { is_tty = 0; #if 0 /* to make getpass work with redirected stdin */ return_value = NULL; goto out2; #endif } #ifdef USE_SETJMP /* * If we get a SIGINT, sig_catch() will jump here - * no need to press Enter after Ctrl-C. */ if (sigsetjmp(intr, 1)) goto out; #endif #ifdef HAVE_SIGACTION sigact.sa_handler = sig_catch; sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; sigaction(SIGINT, &sigact, &old_sigact); #else old_signal = signal(SIGINT, sig_catch); #endif if (is_tty) { TERMIO new_modes = old_modes; if (max_asterisks < 0) new_modes.c_lflag |= ICANON; else new_modes.c_lflag &= ~(ICANON); if (with_echo) new_modes.c_lflag |= (ECHO | ECHOE | ECHOK); else new_modes.c_lflag &= ~(ECHO | ECHOE | ECHOK); new_modes.c_lflag |= ECHONL; if (STTY(fileno(ifp), &new_modes)) goto out; } /* * the prompt is output, and the response read without * echoing. the trailing newline must be removed. if * the fgets() returns an error, a NULL pointer is * returned. */ if ((fputs(prompt, ofp) != EOF) && (fflush(ofp) != EOF)) return_value = readpass(ifp, ofp, with_echo, max_asterisks); out: /* * the old SIGINT handler is restored after the tty * modes. then /dev/tty is closed if it was opened in * the beginning. finally, if a signal was caught it * is sent to this process for normal processing. */ if (is_tty) { if (STTY(fileno(ifp), &old_modes)) return_value = NULL; } #ifdef HAVE_SIGACTION (void) sigaction (SIGINT, &old_sigact, NULL); #else (void) signal (SIGINT, old_signal); #endif #if 0 out2: #endif if (tty_opened) (void) fclose(ifp); if (sig_caught) { kill(getpid(), SIGINT); return_value = NULL; } if (!return_value) { nostring[0] = '\0'; return_value = nostring; } return return_value; }
int main(int argc, char *argv[]) { FILE * infile; FILE * outfile; int dec = 0; size_t maxmem = 0; double maxmemfrac = 0.5; double maxtime = 300.0; int ch; char * passwd; int rc; WARNP_INIT; /* We should have "enc" or "dec" first. */ if (argc < 2) usage(); if (strcmp(argv[1], "enc") == 0) { maxmem = 0; maxmemfrac = 0.125; maxtime = 5.0; } else if (strcmp(argv[1], "dec") == 0) { dec = 1; } else usage(); argc--; argv++; /* Parse arguments. */ while ((ch = getopt(argc, argv, "hm:M:t:")) != -1) { switch (ch) { case 'M': maxmem = strtoumax(optarg, NULL, 0); break; case 'm': maxmemfrac = strtod(optarg, NULL); break; case 't': maxtime = strtod(optarg, NULL); break; default: usage(); } } argc -= optind; argv += optind; /* We must have one or two parameters left. */ if ((argc < 1) || (argc > 2)) usage(); /* If the input isn't stdin, open the file. */ if (strcmp(argv[0], "-")) { if ((infile = fopen(argv[0], "r")) == NULL) { warnp("Cannot open input file: %s", argv[0]); exit(1); } } else { infile = stdin; } /* If we have an output file, open it. */ if (argc > 1) { if ((outfile = fopen(argv[1], "w")) == NULL) { warnp("Cannot open output file: %s", argv[1]); exit(1); } } else { outfile = stdout; } /* Prompt for a password. */ if (readpass(&passwd, "Please enter passphrase", dec ? NULL : "Please confirm passphrase", 1)) exit(1); /* Encrypt or decrypt. */ if (dec) rc = scryptdec_file(infile, outfile, (uint8_t *)passwd, strlen(passwd), maxmem, maxmemfrac, maxtime); else rc = scryptenc_file(infile, outfile, (uint8_t *)passwd, strlen(passwd), maxmem, maxmemfrac, maxtime); /* Zero and free the password. */ memset(passwd, 0, strlen(passwd)); free(passwd); /* If we failed, print the right error message and exit. */ if (rc != 0) { switch (rc) { case 1: warnp("Error determining amount of available memory"); break; case 2: warnp("Error reading clocks"); break; case 3: warnp("Error computing derived key"); break; case 4: warnp("Error reading salt"); break; case 5: warnp("OpenSSL error"); break; case 6: warnp("Error allocating memory"); break; case 7: warn0("Input is not valid scrypt-encrypted block"); break; case 8: warn0("Unrecognized scrypt format version"); break; case 9: warn0("Decrypting file would require too much memory"); break; case 10: warn0("Decrypting file would take too much CPU time"); break; case 11: warn0("Passphrase is incorrect"); break; case 12: warnp("Error writing file: %s", (argc > 1) ? argv[1] : "standard output"); break; case 13: warnp("Error reading file: %s", argv[0]); break; } exit(1); } return (0); }
int main(int argc, char **argv) { const char * newkeyfile = NULL; int keyswanted = 0; char * tok, * brkb = NULL, * eptr; long keynum; uint64_t machinenum = (uint64_t)(-1); uint64_t kfmachinenum; const char * missingkey; int passphrased = 0; uint64_t maxmem = 0; double maxtime = 1.0; char * passphrase; const char * print_key_id_file = NULL; const char * print_key_permissions_file = NULL; const char * ch; char * optarg_copy; /* for strtok_r. */ WARNP_INIT; /* Initialize key cache. */ if (crypto_keys_init()) { warnp("Key cache initialization failed"); exit(1); } /* Parse arguments. */ while ((ch = GETOPT(argc, argv)) != NULL) { GETOPT_SWITCH(ch) { GETOPT_OPTARG("--outkeyfile"): if (newkeyfile != NULL) usage(); newkeyfile = optarg; break; GETOPT_OPT("-r"): keyswanted |= CRYPTO_KEYMASK_READ; break; GETOPT_OPT("-w"): keyswanted |= CRYPTO_KEYMASK_WRITE; break; GETOPT_OPT("-d"): /* * Deleting data requires both delete authorization * and being able to read archives -- we need to be * able to figure out which bits are part of the * archive. */ keyswanted |= CRYPTO_KEYMASK_READ; keyswanted |= CRYPTO_KEYMASK_AUTH_DELETE; break; GETOPT_OPT("--nuke"): keyswanted |= CRYPTO_KEYMASK_AUTH_DELETE; break; GETOPT_OPTARG("--keylist"): /* * This is a deliberately undocumented option used * mostly for testing purposes; it allows a list of * keys to be specified according to their numbers in * crypto/crypto.h instead of using the predefined * sets of "read", "write" and "delete" keys. */ if ((optarg_copy = strdup(optarg)) == NULL) { warn0("Out of memory"); exit(0); } for (tok = strtok_r(optarg_copy, ",", &brkb); tok; tok = strtok_r(NULL, ",", &brkb)) { keynum = strtol(tok, &eptr, 0); if ((eptr == tok) || (keynum < 0) || (keynum > 31)) { warn0("Not a valid key number: %s", tok); free(optarg_copy); exit(1); } keyswanted |= (uint32_t)(1) << keynum; } free(optarg_copy); break; GETOPT_OPTARG("--passphrase-mem"): if (maxmem != 0) usage(); if (humansize_parse(optarg, &maxmem)) { warnp("Cannot parse --passphrase-mem" " argument: %s", optarg); exit(1); } break; GETOPT_OPTARG("--passphrase-time"): if (maxtime != 1.0) usage(); maxtime = strtod(optarg, NULL); if ((maxtime < 0.05) || (maxtime > 86400)) { warn0("Invalid --passphrase-time argument: %s", optarg); exit(1); } break; GETOPT_OPT("--passphrased"): if (passphrased != 0) usage(); passphrased = 1; break; GETOPT_OPTARG("--print-key-id"): if (print_key_id_file != NULL) usage(); print_key_id_file = optarg; break; GETOPT_OPTARG("--print-key-permissions"): if (print_key_permissions_file != NULL) usage(); print_key_permissions_file = optarg; break; GETOPT_MISSING_ARG: warn0("Missing argument to %s\n", ch); /* FALLTHROUGH */ GETOPT_DEFAULT: usage(); } } argc -= optind; argv += optind; /* We can't print ID and permissions at the same time. */ if ((print_key_id_file != NULL) && (print_key_permissions_file != NULL)) usage(); if ((print_key_id_file != NULL) || (print_key_permissions_file != NULL)) { /* We can't combine printing info with generating a new key. */ if (newkeyfile != NULL) usage(); /* We should have processed all arguments. */ if (argc != 0) usage(); /* Print info. */ if (print_key_id_file != NULL) print_id(print_key_id_file); if (print_key_permissions_file != NULL) print_permissions(print_key_permissions_file); } /* We should have an output key file. */ if (newkeyfile == NULL) usage(); /* * It doesn't make sense to specify --passphrase-mem or * --passphrase-time if we're not using a passphrase. */ if (((maxmem != 0) || (maxtime != 1.0)) && (passphrased == 0)) usage(); /* Warn the user if they're being silly. */ if (keyswanted == 0) { warn0("None of {-r, -w, -d, --nuke} options are specified." " This will create a key file with no keys, which is" " probably not what you intended."); } /* Read the specified key files. */ while (argc-- > 0) { /* * Suck in the key file. We could mask this to only load the * keys we want to copy, but there's no point really since we * export keys selectively. */ if (keyfile_read(argv[0], &kfmachinenum, ~0)) { warnp("Cannot read key file: %s", argv[0]); exit(1); } /* * Check that we're not using key files which belong to * different machines. */ if (machinenum == (uint64_t)(-1)) { machinenum = kfmachinenum; } else if (machinenum != kfmachinenum) { warn0("Keys from %s do not belong to the " "same machine as earlier keys", argv[0]); exit(1); } /* Move on to the next file. */ argv++; } /* Make sure that we have the necessary keys. */ if ((missingkey = crypto_keys_missing(keyswanted)) != NULL) { warn0("The %s key is required but not in any input key files", missingkey); exit(1); } /* If the user wants to passphrase the keyfile, get the passphrase. */ if (passphrased != 0) { if (readpass(&passphrase, "Please enter passphrase for keyfile encryption", "Please confirm passphrase for keyfile encryption", 1)) { warnp("Error reading password"); exit(1); } } else { passphrase = NULL; } /* Write out new key file. */ if (keyfile_write(newkeyfile, machinenum, keyswanted, passphrase, maxmem, maxtime)) exit(1); /* Success! */ return (0); }
int keygen_actual(struct register_internal * C, const char * keyfilename, const int passphrased, const uint64_t maxmem, const double maxtime, const char *oldkeyfilename) { FILE * keyfile; char * passphrase = NULL; int keymask = CRYPTO_KEYMASK_USER; uint64_t dummy; /* Sanity-check the user name. */ if (strlen(C->user) > 255) { fprintf(stderr, "User name too long: %s\n", C->user); goto err0; } if (strlen(C->user) == 0) { fprintf(stderr, "User name must be non-empty\n"); goto err0; } /* Sanity-check the machine name. */ if (strlen(C->name) > 255) { fprintf(stderr, "Machine name too long: %s\n", C->name); goto err0; } if (strlen(C->name) == 0) { fprintf(stderr, "Machine name must be non-empty\n"); goto err0; } /* Get a password. */ if (readpass(&C->passwd, "Enter tarsnap account password", NULL, 0)) { warnp("Error reading password"); goto err0; } /* * Create key file -- we do this now rather than later so that we * avoid registering with the server if we won't be able to create * the key file later. */ if ((keyfile = keyfile_write_open(keyfilename)) == NULL) { warnp("Cannot create %s", keyfilename); goto err1; } /* Initialize key cache. */ if (crypto_keys_init()) { warnp("Key cache initialization failed"); goto err3; } /* keyregen (with oldkeyfilename) only regenerates certain keys. */ if (oldkeyfilename != NULL) { /* * Load the keys CRYPTO_KEY_HMAC_{CHUNK, NAME, CPARAMS} * from the old key file, since these are the keys which need * to be consistent in order for two key sets to be * compatible. (CHUNK and NAME are used to compute the * 32-byte keys for blocks; CPARAMS is used to compute * parameters used to split a stream of bytes into chunks.) */ if (keyfile_read(oldkeyfilename, &dummy, CRYPTO_KEYMASK_HMAC_CHUNK | CRYPTO_KEYMASK_HMAC_NAME | CRYPTO_KEYMASK_HMAC_CPARAMS)) { warnp("Error reading old key file"); goto err3; } /* * Adjust the keymask to avoid regenerating keys we read from * the old keyfile. */ keymask &= ~CRYPTO_KEYMASK_HMAC_CHUNK & ~CRYPTO_KEYMASK_HMAC_NAME & ~CRYPTO_KEYMASK_HMAC_CPARAMS; } /* Generate keys. */ if (crypto_keys_generate(keymask)) { warnp("Error generating keys"); goto err3; } /* Register the keys with the server. */ if (keygen_network_register(C) != 0) goto err3; /* Exit with a code of 1 if we couldn't register. */ if (C->machinenum == (uint64_t)(-1)) goto err3; /* If the user wants to passphrase the keyfile, get the passphrase. */ if (passphrased != 0) { if (readpass(&passphrase, "Please enter passphrase for keyfile encryption", "Please confirm passphrase for keyfile encryption", 1)) { warnp("Error reading password"); goto err3; } } /* Write keys to file. */ if (keyfile_write_file(keyfile, C->machinenum, CRYPTO_KEYMASK_USER, passphrase, maxmem, maxtime)) goto err3; /* Close the key file. */ if (fclose(keyfile)) { warnp("Error closing key file"); goto err2; } /* Free allocated memory. C->passwd is a NUL-terminated string. */ insecure_memzero(C->passwd, strlen(C->passwd)); free(C->passwd); /* Free passphrase, if used. passphrase is a NUL-terminated string. */ if (passphrase != NULL) { insecure_memzero(passphrase, strlen(passphrase)); free(passphrase); } /* Success! */ return (0); err3: fclose(keyfile); err2: unlink(keyfilename); err1: insecure_memzero(C->passwd, strlen(C->passwd)); free(C->passwd); if (passphrase != NULL) { insecure_memzero(passphrase, strlen(passphrase)); free(passphrase); } err0: /* Failure! */ return (-1); }