if (state->ssh2)
if (state->ssh2) { state->ssh2key.data = &state->key; state->ssh2key.alg = &ssh_rsa;
static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,                                 WPARAM wParam, LPARAM lParam) {    enum {        controlidstart = 100,        IDC_TITLE,        IDC_BOX_KEY,        IDC_NOKEY,        IDC_GENERATING,        IDC_PROGRESS,        IDC_PKSTATIC, IDC_KEYDISPLAY,        IDC_FPSTATIC, IDC_FINGERPRINT,        IDC_COMMENTSTATIC, IDC_COMMENTEDIT,        IDC_PASSPHRASE1STATIC, IDC_PASSPHRASE1EDIT,        IDC_PASSPHRASE2STATIC, IDC_PASSPHRASE2EDIT,        IDC_BOX_ACTIONS,        IDC_GENSTATIC, IDC_GENERATE,        IDC_LOADSTATIC, IDC_LOAD,        IDC_SAVESTATIC, IDC_SAVE,        IDC_BOX_PARAMS,	IDC_TYPESTATIC, IDC_KEYSSH1, IDC_KEYSSH2RSA,        IDC_BITSSTATIC, IDC_BITS,        IDC_ABOUT,    };    static const int nokey_ids[] = { IDC_NOKEY, 0 };    static const int generating_ids[] = { IDC_GENERATING, IDC_PROGRESS, 0 };    static const int gotkey_ids[] = {        IDC_PKSTATIC, IDC_KEYDISPLAY,        IDC_FPSTATIC, IDC_FINGERPRINT,        IDC_COMMENTSTATIC, IDC_COMMENTEDIT,        IDC_PASSPHRASE1STATIC, IDC_PASSPHRASE1EDIT,        IDC_PASSPHRASE2STATIC, IDC_PASSPHRASE2EDIT, 0 };    static const char generating_msg[] =        "Please wait while a key is generated...";    static const char entropy_msg[] =        "Please generate some randomness by moving the mouse over the blank area.";    struct MainDlgState *state;    switch (msg) {      case WM_INITDIALOG:	/*	 * Centre the window.	 */	{			       /* centre the window */	    RECT rs, rd;	    HWND hw;	    hw = GetDesktopWindow();	    if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))		MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,			    (rs.bottom + rs.top + rd.top - rd.bottom)/2,			    rd.right-rd.left, rd.bottom-rd.top, TRUE);	}        state = smalloc(sizeof(*state));        state->generation_thread_exists = FALSE;        state->collecting_entropy = FALSE;        state->entropy = NULL;        state->key_exists = FALSE;        SetWindowLong(hwnd, GWL_USERDATA, (LONG)state);        {            struct ctlpos cp, cp2;	    /* Accelerators used: acglops */            ctlposinit(&cp, hwnd, 10, 10, 10);            bartitle(&cp, "Public and private key generation for PuTTY",                    IDC_TITLE);            beginbox(&cp, "Key",                     IDC_BOX_KEY);            cp2 = cp;            statictext(&cp2, "No key.", IDC_NOKEY);            cp2 = cp;            statictext(&cp2, "",                       IDC_GENERATING);            progressbar(&cp2, IDC_PROGRESS);            bigeditctrl(&cp,                        "&Public key for pasting into authorized_keys file:",                        IDC_PKSTATIC, IDC_KEYDISPLAY, 7);            SendDlgItemMessage(hwnd, IDC_KEYDISPLAY, EM_SETREADONLY, 1, 0);            staticedit(&cp, "Key fingerprint:", IDC_FPSTATIC,                       IDC_FINGERPRINT, 75);            SendDlgItemMessage(hwnd, IDC_FINGERPRINT, EM_SETREADONLY, 1, 0);            staticedit(&cp, "Key &comment:", IDC_COMMENTSTATIC,                       IDC_COMMENTEDIT, 75);            staticpassedit(&cp, "Key p&assphrase:", IDC_PASSPHRASE1STATIC,                           IDC_PASSPHRASE1EDIT, 75);            staticpassedit(&cp, "C&onfirm passphrase:", IDC_PASSPHRASE2STATIC,                           IDC_PASSPHRASE2EDIT, 75);            endbox(&cp);            beginbox(&cp, "Actions",                     IDC_BOX_ACTIONS);            staticbtn(&cp, "Generate a public/private key pair",                      IDC_GENSTATIC, "&Generate", IDC_GENERATE);            staticbtn(&cp, "Load an existing private key file",                      IDC_LOADSTATIC, "&Load", IDC_LOAD);            staticbtn(&cp, "Save the generated key to a new file",                      IDC_SAVESTATIC, "&Save", IDC_SAVE);            endbox(&cp);            beginbox(&cp, "Parameters",                     IDC_BOX_PARAMS);	    radioline(&cp, "Type of key to generate:", IDC_TYPESTATIC, 2,                          "SSH&1 (RSA)", IDC_KEYSSH1,                          "SSH2 &RSA", IDC_KEYSSH2RSA, NULL);            staticedit(&cp, "Number of &bits in a generated key:",		       IDC_BITSSTATIC, IDC_BITS, 20);            endbox(&cp);        }	CheckRadioButton(hwnd, IDC_KEYSSH1, IDC_KEYSSH2RSA, IDC_KEYSSH1);	SetDlgItemInt(hwnd, IDC_BITS, DEFAULT_KEYSIZE, FALSE);        /*         * Initially, hide the progress bar and the key display,         * and show the no-key display. Also disable the Save         * button, because with no key we obviously can't save         * anything.         */        hidemany(hwnd, nokey_ids, FALSE);        hidemany(hwnd, generating_ids, TRUE);        hidemany(hwnd, gotkey_ids, TRUE);        EnableWindow(GetDlgItem(hwnd, IDC_SAVE), 0);	return 1;      case WM_MOUSEMOVE:        state = (struct MainDlgState *)GetWindowLong(hwnd, GWL_USERDATA);        if (state->collecting_entropy &&            state->entropy &&            state->entropy_got < state->entropy_required) {            state->entropy[state->entropy_got++] = lParam;            state->entropy[state->entropy_got++] = GetMessageTime();            SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS,                               state->entropy_got, 0);            if (state->entropy_got >= state->entropy_required) {                struct rsa_key_thread_params *params;                DWORD threadid;                /*                 * Seed the entropy pool                 */                random_add_heavynoise(state->entropy, state->entropy_size);                memset(state->entropy, 0, state->entropy_size);                sfree(state->entropy);                state->collecting_entropy = FALSE;                SetDlgItemText(hwnd, IDC_GENERATING, generating_msg);                SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETRANGE, 0,                                   MAKELPARAM(0, PROGRESSRANGE));                SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS, 0, 0);                params = smalloc(sizeof(*params));                params->progressbar = GetDlgItem(hwnd, IDC_PROGRESS);                params->dialog = hwnd;		params->keysize = state->keysize;                params->key = &state->key;                if (!CreateThread(NULL, 0, generate_rsa_key_thread,                                  params, 0, &threadid)) {                    MessageBox(hwnd, "Out of thread resources",                               "Key generation error",                               MB_OK | MB_ICONERROR);                    sfree(params);                } else {                    state->generation_thread_exists = TRUE;                }            }        }        break;      case WM_COMMAND:	switch (LOWORD(wParam)) {	  case IDC_COMMENTEDIT:	    if (HIWORD(wParam) == EN_CHANGE) {                state = (struct MainDlgState *)                    GetWindowLong(hwnd, GWL_USERDATA);                if (state->key_exists) {                    HWND editctl = GetDlgItem(hwnd, IDC_COMMENTEDIT);                    int len = GetWindowTextLength(editctl);                    if (*state->commentptr)                        sfree(*state->commentptr);                    *state->commentptr = smalloc(len+1);                    GetWindowText(editctl, *state->commentptr, len+1);                }                            }	    break;	  case IDC_ABOUT:	    EnableWindow(hwnd, 0);	    DialogBox (hinst, MAKEINTRESOURCE(213), NULL, AboutProc);	    EnableWindow(hwnd, 1);            SetActiveWindow(hwnd);	    return 0;          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);                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);                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_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;		    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);                        /*                         * 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, &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, &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;	}	return 0;      case WM_DONEKEY:        state = (struct MainDlgState *)GetWindowLong(hwnd, GWL_USERDATA);        state->generation_thread_exists = FALSE;        state->key_exists = TRUE;        SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS, PROGRESSRANGE, 0);        EnableWindow(GetDlgItem(hwnd, IDC_GENERATE), 1);        EnableWindow(GetDlgItem(hwnd, IDC_LOAD), 1);        EnableWindow(GetDlgItem(hwnd, IDC_SAVE), 1);	if (state->ssh2)	    state->commentptr = &state->ssh2key.comment;	else	    state->commentptr = &state->key.comment;        /*         * Invent a comment for the key. We'll do this by including         * the date in it. This will be so horrifyingly ugly that         * the user will immediately want to change it, which is         * what we want :-)         */        *state->commentptr = smalloc(30);        {            time_t t;            struct tm *tm;            time(&t);            tm = localtime(&t);            strftime(*state->commentptr, 30, "rsa-key-%Y%m%d", tm);        }                    /*         * Now update the key controls with all the key data.         */        {	    char *savecomment;            /*             * Blank passphrase, initially. This isn't dangerous,             * because we will warn (Are You Sure?) before allowing             * the user to save an unprotected private key.             */            SetDlgItemText(hwnd, IDC_PASSPHRASE1EDIT, "");            SetDlgItemText(hwnd, IDC_PASSPHRASE2EDIT, "");            /*             * Set the comment.             */            SetDlgItemText(hwnd, IDC_COMMENTEDIT, *state->commentptr);            /*             * Set the key fingerprint.             */	    savecomment = *state->commentptr;	    *state->commentptr = NULL;            if (state->ssh2) {		char *fp;                fp = state->ssh2key.alg->fingerprint(state->ssh2key.data);		SetDlgItemText(hwnd, IDC_FINGERPRINT, fp);		sfree(fp);	    } else {		char buf[128];                rsa_fingerprint(buf, sizeof(buf), &state->key);		SetDlgItemText(hwnd, IDC_FINGERPRINT, buf);            }	    *state->commentptr = savecomment;            /*             * Construct a decimal representation of the key, for             * pasting into .ssh/authorized_keys on a Unix box.             */	    if (state->ssh2) {		setupbigedit2(hwnd, IDC_KEYDISPLAY, &state->ssh2key);	    } else {		setupbigedit1(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);        break;      case WM_CLOSE:        state = (struct MainDlgState *)GetWindowLong(hwnd, GWL_USERDATA);        sfree(state);        EndDialog(hwnd, 1);	return 0;    }    return 0;}