+ if (comment)
+ sfree(comment);
+
+ if (type == SSH_KEYTYPE_SSH1) {
+ if (!pageant_local) {
+ 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 = snewn(reqlen, unsigned char);
+
+ 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_synchronous(request, reqlen, &vresponse, &resplen);
+ response = vresponse;
+ if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS) {
+ *retstr = dupstr("The already running Pageant "
+ "refused to add the key.");
+ freersakey(rkey);
+ sfree(rkey);
+ sfree(request);
+ sfree(response);
+ return PAGEANT_ACTION_FAILURE;
+ }
+ freersakey(rkey);
+ sfree(rkey);
+ sfree(request);
+ sfree(response);
+ } else {
+ if (!pageant_add_ssh1_key(rkey)) {
+ freersakey(rkey);
+ sfree(rkey); /* already present, don't waste RAM */
+ }
+ }
+ } else {
+ if (!pageant_local) {
+ 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 = snewn(reqlen, unsigned char);
+
+ 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);
+ reqlen += clen + 4;
+ PUT_32BIT(request, reqlen - 4);
+
+ agent_query_synchronous(request, reqlen, &vresponse, &resplen);
+ response = vresponse;
+ if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS) {
+ *retstr = dupstr("The already running Pageant "
+ "refused to add the key.");
+ sfree(request);
+ sfree(response);
+ return PAGEANT_ACTION_FAILURE;
+ }
+
+ sfree(request);
+ sfree(response);
+ } else {
+ if (!pageant_add_ssh2_key(skey)) {
+ skey->alg->freekey(skey->data);
+ sfree(skey); /* already present, don't waste RAM */
+ }
+ }