- case IDC_GENERATE:
- state = (struct MainDlgState *)GetWindowLong(hwnd, GWL_USERDATA);
- if (!state->generation_thread_exists) {
- hidemany(hwnd, nokey_ids, TRUE);
- hidemany(hwnd, generating_ids, FALSE);
- hidemany(hwnd, gotkey_ids, TRUE);
- EnableWindow(GetDlgItem(hwnd, IDC_GENERATE), 0);
- EnableWindow(GetDlgItem(hwnd, IDC_LOAD), 0);
- EnableWindow(GetDlgItem(hwnd, IDC_SAVE), 0);
- state->key_exists = FALSE;
- SetDlgItemText(hwnd, IDC_GENERATING, entropy_msg);
- state->collecting_entropy = TRUE;
-
- /*
- * My brief statistical tests on mouse movements
- * suggest that there are about 5 bits of
- * randomness in the x position, 5 in the y
- * position, and 1.7 in the message time, making
- * 11.7 bits of unpredictability per mouse
- * movement. However, other people have told me
- * it's far less than that, so I'm going to be
- * stupidly cautious and knock that down to a nice
- * round 4.
- */
- state->entropy_required = (KEYSIZE / 4) * 2;
- state->entropy_got = 0;
- state->entropy_size = (state->entropy_required *
- sizeof(*state->entropy));
- state->entropy = malloc(state->entropy_size);
-
- SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETRANGE, 0,
- MAKELPARAM(0, state->entropy_required));
- SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS, 0, 0);
- }
- break;
- case IDC_SAVE:
- state = (struct MainDlgState *)GetWindowLong(hwnd, GWL_USERDATA);
- if (state->key_exists) {
- char filename[FILENAME_MAX];
- char passphrase[PASSPHRASE_MAXLEN];
- GetDlgItemText(hwnd, IDC_PASSPHRASEEDIT,
- passphrase, sizeof(passphrase)-1);
- if (!*passphrase) {
- int ret;
- ret = MessageBox(hwnd,
- "Are you sure you want to save this key\n"
- "without a passphrase to protect it?",
- "PuTTYgen Warning",
- MB_YESNO | MB_ICONWARNING);
- if (ret != IDYES)
- break;
- }
- if (prompt_keyfile(hwnd, "Save private key as:",
- filename, 1)) {
- /* FIXME: prompt before overwriting */
- saversakey(filename, &state->key, &state->aux,
- *passphrase ? passphrase : NULL);
- /* FIXME: check return value */
- }
- }
- break;
- case IDC_LOAD:
- state = (struct MainDlgState *)GetWindowLong(hwnd, GWL_USERDATA);
- if (!state->generation_thread_exists) {
- char filename[FILENAME_MAX];
- if (prompt_keyfile(hwnd, "Load private key:",
- filename, 0)) {
- char passphrase[PASSPHRASE_MAXLEN];
- int needs_pass;
- int ret;
- char *comment;
- struct PassphraseProcStruct pps;
- struct RSAKey newkey;
- struct RSAAux newaux;
-
- needs_pass = rsakey_encrypted(filename, &comment);
- pps.passphrase = passphrase;
- pps.comment = comment;
- do {
- if (needs_pass) {
- int dlgret;
- dlgret = DialogBoxParam(hinst,
- MAKEINTRESOURCE(210),
- NULL, PassphraseProc,
- (LPARAM)&pps);
- if (!dlgret) {
- ret = -2;
- break;
- }
- } else
- *passphrase = '\0';
- ret = loadrsakey(filename, &newkey, &newaux,
- passphrase);
- } while (ret == -1);
- if (comment) free(comment);
- if (ret == 0) {
- MessageBox(NULL, "Couldn't load private key.",
- "PuTTYgen Error", MB_OK | MB_ICONERROR);
- } else if (ret == 1) {
- state->key = newkey;
- state->aux = newaux;
-
- EnableWindow(GetDlgItem(hwnd, IDC_GENERATE), 1);
- EnableWindow(GetDlgItem(hwnd, IDC_LOAD), 1);
- EnableWindow(GetDlgItem(hwnd, IDC_SAVE), 1);
- /*
- * Now update the key controls with all the
- * key data.
- */
- {
- char buf[128];
- SetDlgItemText(hwnd, IDC_PASSPHRASEEDIT,
- passphrase);
- SetDlgItemText(hwnd, IDC_COMMENTEDIT,
- state->key.comment);
- /*
- * Set the key fingerprint.
- */
- {
- char *savecomment = state->key.comment;
- state->key.comment = NULL;
- rsa_fingerprint(buf, sizeof(buf), &state->key);
- state->key.comment = savecomment;
- }
- SetDlgItemText(hwnd, IDC_FINGERPRINT, buf);
- /*
- * Construct a decimal representation
- * of the key, for pasting into
- * .ssh/authorized_keys on a Unix box.
- */
- setupbigedit(hwnd, IDC_KEYDISPLAY, &state->key);
- }
- /*
- * Finally, hide the progress bar and show
- * the key data.
- */
- hidemany(hwnd, nokey_ids, TRUE);
- hidemany(hwnd, generating_ids, TRUE);
- hidemany(hwnd, gotkey_ids, FALSE);
- state->key_exists = TRUE;
- }
- }
- }
- break;
+ case IDC_GENERATE:
+ state =
+ (struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
+ if (!state->generation_thread_exists) {
+ BOOL ok;
+ state->keysize = GetDlgItemInt(hwnd, IDC_BITS, &ok, FALSE);
+ if (!ok)
+ state->keysize = DEFAULT_KEYSIZE;
+ /* If we ever introduce a new key type, check it here! */
+ state->ssh2 = !IsDlgButtonChecked(hwnd, IDC_KEYSSH1);
+ state->is_dsa = IsDlgButtonChecked(hwnd, IDC_KEYSSH2DSA);
+ if (state->keysize < 256) {
+ int ret = MessageBox(hwnd,
+ "PuTTYgen will not generate a key"
+ " smaller than 256 bits.\n"
+ "Key length reset to 256. Continue?",
+ "PuTTYgen Warning",
+ MB_ICONWARNING | MB_OKCANCEL);
+ if (ret != IDOK)
+ break;
+ state->keysize = 256;
+ SetDlgItemInt(hwnd, IDC_BITS, 256, FALSE);
+ }
+ hidemany(hwnd, nokey_ids, TRUE);
+ hidemany(hwnd, generating_ids, FALSE);
+ hidemany(hwnd, gotkey_ids, TRUE);
+ EnableWindow(GetDlgItem(hwnd, IDC_GENERATE), 0);
+ EnableWindow(GetDlgItem(hwnd, IDC_LOAD), 0);
+ EnableWindow(GetDlgItem(hwnd, IDC_SAVE), 0);
+ EnableWindow(GetDlgItem(hwnd, IDC_SAVEPUB), 0);
+ EnableWindow(GetDlgItem(hwnd, IDC_KEYSSH1), 0);
+ EnableWindow(GetDlgItem(hwnd, IDC_KEYSSH2RSA), 0);
+ EnableWindow(GetDlgItem(hwnd, IDC_BITS), 0);
+ state->key_exists = FALSE;
+ SetDlgItemText(hwnd, IDC_GENERATING, entropy_msg);
+ state->collecting_entropy = TRUE;
+
+ /*
+ * My brief statistical tests on mouse movements
+ * suggest that there are about 2.5 bits of
+ * randomness in the x position, 2.5 in the y
+ * position, and 1.7 in the message time, making
+ * 5.7 bits of unpredictability per mouse movement.
+ * However, other people have told me it's far less
+ * than that, so I'm going to be stupidly cautious
+ * and knock that down to a nice round 2. With this
+ * method, we require two words per mouse movement,
+ * so with 2 bits per mouse movement we expect 2
+ * bits every 2 words.
+ */
+ state->entropy_required = (state->keysize / 2) * 2;
+ state->entropy_got = 0;
+ state->entropy_size = (state->entropy_required *
+ sizeof(*state->entropy));
+ state->entropy = smalloc(state->entropy_size);
+
+ SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETRANGE, 0,
+ MAKELPARAM(0, state->entropy_required));
+ SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS, 0, 0);
+ }
+ break;
+ case IDC_SAVE:
+ state =
+ (struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
+ if (state->key_exists) {
+ char filename[FILENAME_MAX];
+ char passphrase[PASSPHRASE_MAXLEN];
+ char passphrase2[PASSPHRASE_MAXLEN];
+ GetDlgItemText(hwnd, IDC_PASSPHRASE1EDIT,
+ passphrase, sizeof(passphrase));
+ GetDlgItemText(hwnd, IDC_PASSPHRASE2EDIT,
+ passphrase2, sizeof(passphrase2));
+ if (strcmp(passphrase, passphrase2)) {
+ MessageBox(hwnd,
+ "The two passphrases given do not match.",
+ "PuTTYgen Error", MB_OK | MB_ICONERROR);
+ break;
+ }
+ if (!*passphrase) {
+ int ret;
+ ret = MessageBox(hwnd,
+ "Are you sure you want to save this key\n"
+ "without a passphrase to protect it?",
+ "PuTTYgen Warning",
+ MB_YESNO | MB_ICONWARNING);
+ if (ret != IDYES)
+ break;
+ }
+ if (prompt_keyfile(hwnd, "Save private key as:",
+ filename, 1)) {
+ int ret;
+ FILE *fp = fopen(filename, "r");
+ if (fp) {
+ char buffer[FILENAME_MAX + 80];
+ fclose(fp);
+ sprintf(buffer, "Overwrite existing file\n%.*s?",
+ FILENAME_MAX, filename);
+ ret = MessageBox(hwnd, buffer, "PuTTYgen Warning",
+ MB_YESNO | MB_ICONWARNING);
+ if (ret != IDYES)
+ break;
+ }
+ if (state->ssh2) {
+ ret = ssh2_save_userkey(filename, &state->ssh2key,
+ *passphrase ? passphrase :
+ NULL);
+ } else {
+ ret = saversakey(filename, &state->key,
+ *passphrase ? passphrase : NULL);
+ }
+ if (ret <= 0) {
+ MessageBox(hwnd, "Unable to save key file",
+ "PuTTYgen Error", MB_OK | MB_ICONERROR);
+ }
+ }
+ }
+ break;
+ case IDC_SAVEPUB:
+ state =
+ (struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
+ if (state->key_exists) {
+ char filename[FILENAME_MAX];
+ if (prompt_keyfile(hwnd, "Save public key as:",
+ filename, 1)) {
+ int ret;
+ FILE *fp = fopen(filename, "r");
+ if (fp) {
+ char buffer[FILENAME_MAX + 80];
+ fclose(fp);
+ sprintf(buffer, "Overwrite existing file\n%.*s?",
+ FILENAME_MAX, filename);
+ ret = MessageBox(hwnd, buffer, "PuTTYgen Warning",
+ MB_YESNO | MB_ICONWARNING);
+ if (ret != IDYES)
+ break;
+ }
+ if (state->ssh2) {
+ ret = save_ssh2_pubkey(filename, &state->ssh2key);
+ } else {
+ ret = save_ssh1_pubkey(filename, &state->key);
+ }
+ if (ret <= 0) {
+ MessageBox(hwnd, "Unable to save key file",
+ "PuTTYgen Error", MB_OK | MB_ICONERROR);
+ }
+ }
+ }
+ break;
+ case IDC_LOAD:
+ state =
+ (struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
+ if (!state->generation_thread_exists) {
+ char filename[FILENAME_MAX];
+ if (prompt_keyfile(hwnd, "Load private key:", filename, 0)) {
+ char passphrase[PASSPHRASE_MAXLEN];
+ int needs_pass;
+ int ver;
+ int ret;
+ char *comment;
+ struct PassphraseProcStruct pps;
+ struct RSAKey newkey1;
+ struct ssh2_userkey *newkey2 = NULL;
+
+ ver = keyfile_version(filename);
+ if (ver == 0) {
+ MessageBox(NULL, "Couldn't load private key.",
+ "PuTTYgen Error", MB_OK | MB_ICONERROR);
+ break;
+ }
+
+ comment = NULL;
+ if (ver == 1)
+ needs_pass = rsakey_encrypted(filename, &comment);
+ else
+ needs_pass =
+ ssh2_userkey_encrypted(filename, &comment);
+ pps.passphrase = passphrase;
+ pps.comment = comment;
+ do {
+ if (needs_pass) {
+ int dlgret;
+ dlgret = DialogBoxParam(hinst,
+ MAKEINTRESOURCE(210),
+ NULL, PassphraseProc,
+ (LPARAM) & pps);
+ if (!dlgret) {
+ ret = -2;
+ break;
+ }
+ } else
+ *passphrase = '\0';
+ if (ver == 1)
+ ret =
+ loadrsakey(filename, &newkey1, passphrase);
+ else {
+ newkey2 =
+ ssh2_load_userkey(filename, passphrase);
+ if (newkey2 == SSH2_WRONG_PASSPHRASE)
+ ret = -1;
+ else if (!newkey2)
+ ret = 0;
+ else
+ ret = 1;
+ }
+ } while (ret == -1);
+ if (comment)
+ sfree(comment);
+ if (ret == 0) {
+ MessageBox(NULL, "Couldn't load private key.",
+ "PuTTYgen Error", MB_OK | MB_ICONERROR);
+ } else if (ret == 1) {
+ EnableWindow(GetDlgItem(hwnd, IDC_GENERATE), 1);
+ EnableWindow(GetDlgItem(hwnd, IDC_LOAD), 1);
+ EnableWindow(GetDlgItem(hwnd, IDC_SAVE), 1);
+ EnableWindow(GetDlgItem(hwnd, IDC_SAVEPUB), 1);
+ EnableWindow(GetDlgItem(hwnd, IDC_KEYSSH1), 1);
+ EnableWindow(GetDlgItem(hwnd, IDC_KEYSSH2RSA), 1);
+ EnableWindow(GetDlgItem(hwnd, IDC_BITS), 1);
+ /*
+ * Now update the key controls with all the
+ * key data.
+ */
+ {
+ SetDlgItemText(hwnd, IDC_PASSPHRASE1EDIT,
+ passphrase);
+ SetDlgItemText(hwnd, IDC_PASSPHRASE2EDIT,
+ passphrase);
+ if (ver == 1) {
+ char buf[128];
+ char *savecomment;
+
+ state->ssh2 = FALSE;
+ state->commentptr = &state->key.comment;
+ state->key = newkey1;
+
+ /*
+ * Set the key fingerprint.
+ */
+ savecomment = state->key.comment;
+ state->key.comment = NULL;
+ rsa_fingerprint(buf, sizeof(buf),
+ &state->key);
+ state->key.comment = savecomment;
+
+ SetDlgItemText(hwnd, IDC_FINGERPRINT, buf);
+ /*
+ * Construct a decimal representation
+ * of the key, for pasting into
+ * .ssh/authorized_keys on a Unix box.
+ */
+ setupbigedit1(hwnd, IDC_KEYDISPLAY,
+ IDC_PKSTATIC, &state->key);
+ } else {
+ char *fp;
+ char *savecomment;
+
+ state->ssh2 = TRUE;
+ state->commentptr =
+ &state->ssh2key.comment;
+ state->ssh2key = *newkey2; /* structure copy */
+ sfree(newkey2);
+
+ savecomment = state->ssh2key.comment;
+ state->ssh2key.comment = NULL;
+ fp =
+ state->ssh2key.alg->
+ fingerprint(state->ssh2key.data);
+ state->ssh2key.comment = savecomment;
+
+ SetDlgItemText(hwnd, IDC_FINGERPRINT, fp);
+ sfree(fp);
+
+ setupbigedit2(hwnd, IDC_KEYDISPLAY,
+ IDC_PKSTATIC, &state->ssh2key);
+ }
+ SetDlgItemText(hwnd, IDC_COMMENTEDIT,
+ *state->commentptr);
+ }
+ /*
+ * Finally, hide the progress bar and show
+ * the key data.
+ */
+ hidemany(hwnd, nokey_ids, TRUE);
+ hidemany(hwnd, generating_ids, TRUE);
+ hidemany(hwnd, gotkey_ids, FALSE);
+ state->key_exists = TRUE;
+ }
+ }
+ }
+ break;