- if (type == SSH_KEYTYPE_SSH1) {
- if (!rsakey_pubblob(filename, &blob, &bloblen)) {
- MessageBox(NULL, "Couldn't load private key.", APPNAME,
- MB_OK | MB_ICONERROR);
- return;
- }
- keylist = get_keylist1();
- } else {
- unsigned char *blob2;
- blob = ssh2_userkey_loadpub(filename, NULL, &bloblen);
- if (!blob) {
- MessageBox(NULL, "Couldn't load private key.", APPNAME,
- MB_OK | MB_ICONERROR);
- return;
- }
- /* For our purposes we want the blob prefixed with its length */
- blob2 = smalloc(bloblen+4);
- PUT_32BIT(blob2, bloblen);
- memcpy(blob2 + 4, blob, bloblen);
- sfree(blob);
- blob = blob2;
-
- keylist = get_keylist2();
- }
- if (keylist) {
- nkeys = GET_32BIT(keylist);
- p = keylist + 4;
-
- for (i = 0; i < nkeys; i++) {
- if (!memcmp(blob, p, bloblen)) {
- /* Key is already present; we can now leave. */
- sfree(keylist);
- sfree(blob);
- return;
- }
- /* Now skip over public blob */
- if (type == SSH_KEYTYPE_SSH1)
- p += rsa_public_blob_len(p);
- else
- p += 4 + GET_32BIT(p);
- /* Now skip over comment field */
- p += 4 + GET_32BIT(p);
- }
-
- sfree(keylist);
- }
-
- sfree(blob);
- }
-
- if (type == SSH_KEYTYPE_SSH1)
- needs_pass = rsakey_encrypted(filename, &comment);
- else
- needs_pass = ssh2_userkey_encrypted(filename, &comment);
- attempts = 0;
- if (type == SSH_KEYTYPE_SSH1)
- rkey = smalloc(sizeof(*rkey));
- pps.passphrase = passphrase;
- pps.comment = comment;
- original_pass = 0;
- do {
- if (needs_pass) {
- /* try all the remembered passphrases first */
- char *pp = index234(passphrases, attempts);
- if(pp) {
- strcpy(passphrase, pp);
- } else {
- int dlgret;
- original_pass = 1;
- dlgret = DialogBoxParam(instance, MAKEINTRESOURCE(210),
- NULL, PassphraseProc, (LPARAM) & pps);
- passphrase_box = NULL;
- if (!dlgret) {
- if (comment)
- sfree(comment);
- if (type == SSH_KEYTYPE_SSH1)
- sfree(rkey);
- return; /* operation cancelled */
- }
- }
- } else
- *passphrase = '\0';
- if (type == SSH_KEYTYPE_SSH1)
- ret = loadrsakey(filename, rkey, passphrase);
- else {
- skey = ssh2_load_userkey(filename, passphrase);
- if (skey == SSH2_WRONG_PASSPHRASE)
- ret = -1;
- else if (!skey)
- ret = 0;
- else
- ret = 1;
- }
- attempts++;
- } while (ret == -1);
-
- /* if they typed in an ok passphrase, remember it */
- if(original_pass && ret) {
- char *pp = dupstr(passphrase);
- addpos234(passphrases, pp, 0);
- }
-
- if (comment)
- sfree(comment);
- if (ret == 0) {
- MessageBox(NULL, "Couldn't load private key.", APPNAME,
- MB_OK | MB_ICONERROR);
- if (type == SSH_KEYTYPE_SSH1)
- sfree(rkey);
- return;
- }
- if (type == SSH_KEYTYPE_SSH1) {
- if (already_running) {
- unsigned char *request, *response;
- void *vresponse;
- int reqlen, clen, resplen;
-
- clen = strlen(rkey->comment);
-
- reqlen = 4 + 1 + /* length, message type */
- 4 + /* bit count */
- ssh1_bignum_length(rkey->modulus) +
- ssh1_bignum_length(rkey->exponent) +
- ssh1_bignum_length(rkey->private_exponent) +
- ssh1_bignum_length(rkey->iqmp) +
- ssh1_bignum_length(rkey->p) +
- ssh1_bignum_length(rkey->q) + 4 + clen /* comment */
- ;
-
- request = smalloc(reqlen);
-
- request[4] = SSH1_AGENTC_ADD_RSA_IDENTITY;
- reqlen = 5;
- PUT_32BIT(request + reqlen, bignum_bitcount(rkey->modulus));
- reqlen += 4;
- reqlen += ssh1_write_bignum(request + reqlen, rkey->modulus);
- reqlen += ssh1_write_bignum(request + reqlen, rkey->exponent);
- reqlen +=
- ssh1_write_bignum(request + reqlen,
- rkey->private_exponent);
- reqlen += ssh1_write_bignum(request + reqlen, rkey->iqmp);
- reqlen += ssh1_write_bignum(request + reqlen, rkey->p);
- reqlen += ssh1_write_bignum(request + reqlen, rkey->q);
- PUT_32BIT(request + reqlen, clen);
- memcpy(request + reqlen + 4, rkey->comment, clen);
- reqlen += 4 + clen;
- PUT_32BIT(request, reqlen - 4);
-
- agent_query(request, reqlen, &vresponse, &resplen);
- response = vresponse;
- if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS)
- MessageBox(NULL, "The already running Pageant "
- "refused to add the key.", APPNAME,
- MB_OK | MB_ICONERROR);
-
- sfree(request);
- sfree(response);
- } else {
- if (add234(rsakeys, rkey) != rkey)
- sfree(rkey); /* already present, don't waste RAM */
- }
- } else {
- if (already_running) {
- unsigned char *request, *response;
- void *vresponse;
- int reqlen, alglen, clen, keybloblen, resplen;
- alglen = strlen(skey->alg->name);
- clen = strlen(skey->comment);
-
- keybloblen = skey->alg->openssh_fmtkey(skey->data, NULL, 0);
-
- reqlen = 4 + 1 + /* length, message type */
- 4 + alglen + /* algorithm name */
- keybloblen + /* key data */
- 4 + clen /* comment */
- ;
-
- request = smalloc(reqlen);
-
- request[4] = SSH2_AGENTC_ADD_IDENTITY;
- reqlen = 5;
- PUT_32BIT(request + reqlen, alglen);
- reqlen += 4;
- memcpy(request + reqlen, skey->alg->name, alglen);
- reqlen += alglen;
- reqlen += skey->alg->openssh_fmtkey(skey->data,
- request + reqlen,
- keybloblen);
- PUT_32BIT(request + reqlen, clen);
- memcpy(request + reqlen + 4, skey->comment, clen);
- PUT_32BIT(request, reqlen - 4);
- reqlen += clen + 4;
-
- agent_query(request, reqlen, &vresponse, &resplen);
- response = vresponse;
- if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS)
- MessageBox(NULL, "The already running Pageant "
- "refused to add the key.", APPNAME,
- MB_OK | MB_ICONERROR);
-
- sfree(request);
- sfree(response);
- } else {
- if (add234(ssh2keys, skey) != skey) {
- skey->alg->freekey(skey->data);
- sfree(skey); /* already present, don't waste RAM */
- }
- }
- }
-}
-
-/*
- * Create an SSH1 key list in a malloc'ed buffer; return its
- * length.
- */
-static void *make_keylist1(int *length)
-{
- int i, nkeys, len;
- struct RSAKey *key;
- unsigned char *blob, *p, *ret;
- int bloblen;
-
- /*
- * Count up the number and length of keys we hold.
- */
- len = 4;
- nkeys = 0;
- for (i = 0; NULL != (key = index234(rsakeys, i)); i++) {
- nkeys++;
- blob = rsa_public_blob(key, &bloblen);
- len += bloblen;
- sfree(blob);
- len += 4 + strlen(key->comment);
- }
-
- /* Allocate the buffer. */
- p = ret = smalloc(len);
- if (length) *length = len;
-
- PUT_32BIT(p, nkeys);
- p += 4;
- for (i = 0; NULL != (key = index234(rsakeys, i)); i++) {
- blob = rsa_public_blob(key, &bloblen);
- memcpy(p, blob, bloblen);
- p += bloblen;
- sfree(blob);
- PUT_32BIT(p, strlen(key->comment));
- memcpy(p + 4, key->comment, strlen(key->comment));
- p += 4 + strlen(key->comment);
- }
-
- assert(p - ret == len);
- return ret;
-}
-
-/*
- * Create an SSH2 key list in a malloc'ed buffer; return its
- * length.
- */
-static void *make_keylist2(int *length)
-{
- struct ssh2_userkey *key;
- int i, len, nkeys;
- unsigned char *blob, *p, *ret;
- int bloblen;
-
- /*
- * Count up the number and length of keys we hold.
- */
- len = 4;
- nkeys = 0;
- for (i = 0; NULL != (key = index234(ssh2keys, i)); i++) {
- nkeys++;
- len += 4; /* length field */
- blob = key->alg->public_blob(key->data, &bloblen);
- len += bloblen;
- sfree(blob);
- len += 4 + strlen(key->comment);
- }
-
- /* Allocate the buffer. */
- p = ret = smalloc(len);
- if (length) *length = len;