+static void
+process_add_identity(SocketEntry *e, int version)
+{
+ Idtab *tab = idtab_lookup(version);
+ int type, success = 0, death = 0, confirm = 0;
+ char *type_name, *comment;
+ Key *k = NULL;
+
+ switch (version) {
+ case 1:
+ k = key_new_private(KEY_RSA1);
+ (void) buffer_get_int(&e->request); /* ignored */
+ buffer_get_bignum(&e->request, k->rsa->n);
+ buffer_get_bignum(&e->request, k->rsa->e);
+ buffer_get_bignum(&e->request, k->rsa->d);
+ buffer_get_bignum(&e->request, k->rsa->iqmp);
+
+ /* SSH and SSL have p and q swapped */
+ buffer_get_bignum(&e->request, k->rsa->q); /* p */
+ buffer_get_bignum(&e->request, k->rsa->p); /* q */
+
+ /* Generate additional parameters */
+ rsa_generate_additional_parameters(k->rsa);
+ break;
+ case 2:
+ type_name = buffer_get_string(&e->request, NULL);
+ type = key_type_from_name(type_name);
+ xfree(type_name);
+ switch (type) {
+ case KEY_DSA:
+ k = key_new_private(type);
+ buffer_get_bignum2(&e->request, k->dsa->p);
+ buffer_get_bignum2(&e->request, k->dsa->q);
+ buffer_get_bignum2(&e->request, k->dsa->g);
+ buffer_get_bignum2(&e->request, k->dsa->pub_key);
+ buffer_get_bignum2(&e->request, k->dsa->priv_key);
+ break;
+ case KEY_RSA:
+ k = key_new_private(type);
+ buffer_get_bignum2(&e->request, k->rsa->n);
+ buffer_get_bignum2(&e->request, k->rsa->e);
+ buffer_get_bignum2(&e->request, k->rsa->d);
+ buffer_get_bignum2(&e->request, k->rsa->iqmp);
+ buffer_get_bignum2(&e->request, k->rsa->p);
+ buffer_get_bignum2(&e->request, k->rsa->q);
+
+ /* Generate additional parameters */
+ rsa_generate_additional_parameters(k->rsa);
+ break;
+ default:
+ buffer_clear(&e->request);
+ goto send;
+ }
+ break;
+ }
+ /* enable blinding */
+ switch (k->type) {
+ case KEY_RSA:
+ case KEY_RSA1:
+ if (RSA_blinding_on(k->rsa, NULL) != 1) {
+ error("process_add_identity: RSA_blinding_on failed");
+ key_free(k);
+ goto send;
+ }
+ break;
+ }
+ comment = buffer_get_string(&e->request, NULL);
+ if (k == NULL) {
+ xfree(comment);
+ goto send;
+ }
+ success = 1;
+ while (buffer_len(&e->request)) {
+ switch (buffer_get_char(&e->request)) {
+ case SSH_AGENT_CONSTRAIN_LIFETIME:
+ death = time(NULL) + buffer_get_int(&e->request);
+ break;
+ case SSH_AGENT_CONSTRAIN_CONFIRM:
+ confirm = 1;
+ break;
+ default:
+ break;