Diff

Differences From Artifact [ab8acc2cb9]:

To Artifact [67cc3cabb0]:


676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
};

struct ssh_tag {
    const struct plug_function_table *fn;
    /* the above field _must_ be first in the structure */

    char *v_c, *v_s;
    SHA_State exhash;

    Socket s;

    void *ldisc;
    void *logctx;

    unsigned char session_key[32];







|







676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
};

struct ssh_tag {
    const struct plug_function_table *fn;
    /* the above field _must_ be first in the structure */

    char *v_c, *v_s;
    void *exhash;

    Socket s;

    void *ldisc;
    void *logctx;

    unsigned char session_key[32];
702
703
704
705
706
707
708

709
710
711
712
713
714
715
    const struct ssh_mac *csmac, *scmac;
    void *cs_mac_ctx, *sc_mac_ctx;
    const struct ssh_compress *cscomp, *sccomp;
    void *cs_comp_ctx, *sc_comp_ctx;
    const struct ssh_kex *kex;
    const struct ssh_signkey *hostkey;
    unsigned char v2_session_id[20];

    void *kex_ctx;

    char *savedhost;
    int savedport;
    int send_ok;
    int echoing, editing;








>







702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
    const struct ssh_mac *csmac, *scmac;
    void *cs_mac_ctx, *sc_mac_ctx;
    const struct ssh_compress *cscomp, *sccomp;
    void *cs_comp_ctx, *sc_comp_ctx;
    const struct ssh_kex *kex;
    const struct ssh_signkey *hostkey;
    unsigned char v2_session_id[20];
    int v2_session_id_len;
    void *kex_ctx;

    char *savedhost;
    int savedport;
    int send_ok;
    int echoing, editing;

1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
    if (av != bv)
	return (av < bv ? -1 : +1);
    return 0;
}

/*
 * Utility routines for putting an SSH-protocol `string' and
 * `uint32' into a SHA state.
 */
static void sha_string(SHA_State * s, void *str, int len)
{
    unsigned char lenblk[4];
    PUT_32BIT(lenblk, len);
    SHA_Bytes(s, lenblk, 4);
    SHA_Bytes(s, str, len);
}

static void sha_uint32(SHA_State * s, unsigned i)
{
    unsigned char intblk[4];
    PUT_32BIT(intblk, i);
    SHA_Bytes(s, intblk, 4);
}

/*
 * Packet construction functions. Mostly shared between SSH-1 and SSH-2.
 */
static void ssh_pkt_ensure(struct Packet *pkt, int length)
{







|

|



|
|


|



|







1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
    if (av != bv)
	return (av < bv ? -1 : +1);
    return 0;
}

/*
 * Utility routines for putting an SSH-protocol `string' and
 * `uint32' into a hash state.
 */
static void hash_string(const struct ssh_hash *h, void *s, void *str, int len)
{
    unsigned char lenblk[4];
    PUT_32BIT(lenblk, len);
    h->bytes(s, lenblk, 4);
    h->bytes(s, str, len);
}

static void hash_uint32(const struct ssh_hash *h, void *s, unsigned i)
{
    unsigned char intblk[4];
    PUT_32BIT(intblk, i);
    h->bytes(s, intblk, 4);
}

/*
 * Packet construction functions. Mostly shared between SSH-1 and SSH-2.
 */
static void ssh_pkt_ensure(struct Packet *pkt, int length)
{
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
    for (i = 0; i < len; i++)
	debug((" %02x", p[i]));
    debug(("\n"));
    sfree(p);
}
#endif

static void sha_mpint(SHA_State * s, Bignum b)
{
    unsigned char *p;
    int len;
    p = ssh2_mpint_fmt(b, &len);
    sha_string(s, p, len);
    sfree(p);
}

/*
 * Packet decode functions for both SSH-1 and SSH-2.
 */
static unsigned long ssh_pkt_getuint32(struct Packet *pkt)







|




|







1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
    for (i = 0; i < len; i++)
	debug((" %02x", p[i]));
    debug(("\n"));
    sfree(p);
}
#endif

static void hash_mpint(const struct ssh_hash *h, void *s, Bignum b)
{
    unsigned char *p;
    int len;
    p = ssh2_mpint_fmt(b, &len);
    hash_string(h, s, p, len);
    sfree(p);
}

/*
 * Packet decode functions for both SSH-1 and SSH-2.
 */
static unsigned long ssh_pkt_getuint32(struct Packet *pkt)
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953

4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
    return 0;
}


/*
 * SSH-2 key creation method.
 */
static void ssh2_mkkey(Ssh ssh, Bignum K, unsigned char *H,
		       unsigned char *sessid, char chr,
		       unsigned char *keyspace)
{

    SHA_State s;
    /* First 20 bytes. */
    SHA_Init(&s);
    if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
	sha_mpint(&s, K);
    SHA_Bytes(&s, H, 20);
    SHA_Bytes(&s, &chr, 1);
    SHA_Bytes(&s, sessid, 20);
    SHA_Final(&s, keyspace);
    /* Next 20 bytes. */
    SHA_Init(&s);
    if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
	sha_mpint(&s, K);
    SHA_Bytes(&s, H, 20);
    SHA_Bytes(&s, keyspace, 20);
    SHA_Final(&s, keyspace + 20);
}

/*
 * Handle the SSH-2 transport layer.
 */
static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
			     struct Packet *pktin)







|
<


>
|
|
|

|
|
|
|
|
|
|

|
|
|
|







4944
4945
4946
4947
4948
4949
4950
4951

4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
    return 0;
}


/*
 * SSH-2 key creation method.
 */
static void ssh2_mkkey(Ssh ssh, Bignum K, unsigned char *H, char chr,

		       unsigned char *keyspace)
{
    const struct ssh_hash *h = ssh->kex->hash;
    void *s;
    /* First hlen bytes. */
    s = h->init();
    if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
	hash_mpint(h, s, K);
    h->bytes(s, H, h->hlen);
    h->bytes(s, &chr, 1);
    h->bytes(s, ssh->v2_session_id, ssh->v2_session_id_len);
    h->final(s, keyspace);
    /* Next hlen bytes. */
    s = h->init();
    if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
	hash_mpint(h, s, K);
    h->bytes(s, H, h->hlen);
    h->bytes(s, keyspace, h->hlen);
    h->final(s, keyspace + h->hlen);
}

/*
 * Handle the SSH-2 transport layer.
 */
static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
			     struct Packet *pktin)
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430

5431
5432
5433

5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
	    if (s->dlgret == 0) {
		ssh_disconnect(ssh, "User aborted at cipher warning", NULL,
			       0, TRUE);
		crStop(0);
	    }
	}

	SHA_Init(&ssh->exhash);
	sha_string(&ssh->exhash, ssh->v_c, strlen(ssh->v_c));
	sha_string(&ssh->exhash, ssh->v_s, strlen(ssh->v_s));

	sha_string(&ssh->exhash, s->our_kexinit, s->our_kexinitlen);
	sfree(s->our_kexinit);
	if (pktin->length > 5)

	    sha_string(&ssh->exhash, pktin->data + 5, pktin->length - 5);


	if (s->ignorepkt) /* first_kex_packet_follows */
	    crWaitUntil(pktin);                /* Ignore packet */
    }

    /*
     * Work out the number of bits of key we will need from the key
     * exchange. We start with the maximum key length of either
     * cipher...
     */
    {
	int csbits, scbits;

	csbits = s->cscipher_tobe->keylen;
	scbits = s->sccipher_tobe->keylen;
	s->nbits = (csbits > scbits ? csbits : scbits);
    }
    /* The keys only have 160-bit entropy, since they're based on
     * a SHA-1 hash. So cap the key size at 160 bits. */
    if (s->nbits > 160)
	s->nbits = 160;

    /*
     * If we're doing Diffie-Hellman group exchange, start by
     * requesting a group.
     */
    if (!ssh->kex->pdata) {
	logevent("Doing Diffie-Hellman group exchange");







|
|
|
>
|


>
|
<

















|
|
|
|







5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437

5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
	    if (s->dlgret == 0) {
		ssh_disconnect(ssh, "User aborted at cipher warning", NULL,
			       0, TRUE);
		crStop(0);
	    }
	}

	ssh->exhash = ssh->kex->hash->init();
	hash_string(ssh->kex->hash, ssh->exhash, ssh->v_c, strlen(ssh->v_c));
	hash_string(ssh->kex->hash, ssh->exhash, ssh->v_s, strlen(ssh->v_s));
	hash_string(ssh->kex->hash, ssh->exhash,
	    s->our_kexinit, s->our_kexinitlen);
	sfree(s->our_kexinit);
	if (pktin->length > 5)
	    hash_string(ssh->kex->hash, ssh->exhash,
		pktin->data + 5, pktin->length - 5);


	if (s->ignorepkt) /* first_kex_packet_follows */
	    crWaitUntil(pktin);                /* Ignore packet */
    }

    /*
     * Work out the number of bits of key we will need from the key
     * exchange. We start with the maximum key length of either
     * cipher...
     */
    {
	int csbits, scbits;

	csbits = s->cscipher_tobe->keylen;
	scbits = s->sccipher_tobe->keylen;
	s->nbits = (csbits > scbits ? csbits : scbits);
    }
    /* The keys only have hlen-bit entropy, since they're based on
     * a hash. So cap the key size at hlen bits. */
    if (s->nbits > ssh->kex->hash->hlen * 8)
	s->nbits = ssh->kex->hash->hlen * 8;

    /*
     * If we're doing Diffie-Hellman group exchange, start by
     * requesting a group.
     */
    if (!ssh->kex->pdata) {
	logevent("Doing Diffie-Hellman group exchange");
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536

5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550

5551
5552
5553
5554
5555
5556
5557

    s->K = dh_find_K(ssh->kex_ctx, s->f);

    /* We assume everything from now on will be quick, and it might
     * involve user interaction. */
    set_busy_status(ssh->frontend, BUSY_NOT);

    sha_string(&ssh->exhash, s->hostkeydata, s->hostkeylen);
    if (ssh->kex == &ssh_diffiehellman_gex) {
	sha_uint32(&ssh->exhash, s->pbits);
	sha_mpint(&ssh->exhash, s->p);
	sha_mpint(&ssh->exhash, s->g);
    }
    sha_mpint(&ssh->exhash, s->e);
    sha_mpint(&ssh->exhash, s->f);
    sha_mpint(&ssh->exhash, s->K);

    SHA_Final(&ssh->exhash, s->exchange_hash);

    dh_cleanup(ssh->kex_ctx);
    ssh->kex_ctx = NULL;

#if 0
    debug(("Exchange hash is:\n"));
    dmemdump(s->exchange_hash, 20);
#endif

    s->hkey = ssh->hostkey->newkey(s->hostkeydata, s->hostkeylen);
    if (!s->hkey ||
	!ssh->hostkey->verifysig(s->hkey, s->sigdata, s->siglen,
				 (char *)s->exchange_hash, 20)) {

	bombout(("Server's host key did not match the signature supplied"));
	crStop(0);
    }

    /*
     * Authenticate remote host: verify host key. (We've already
     * checked the signature of the exchange hash.)







|

|
|
|

|
|
|
>
|






|





|
>







5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561

    s->K = dh_find_K(ssh->kex_ctx, s->f);

    /* We assume everything from now on will be quick, and it might
     * involve user interaction. */
    set_busy_status(ssh->frontend, BUSY_NOT);

    hash_string(ssh->kex->hash, ssh->exhash, s->hostkeydata, s->hostkeylen);
    if (ssh->kex == &ssh_diffiehellman_gex) {
	hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits);
	hash_mpint(ssh->kex->hash, ssh->exhash, s->p);
	hash_mpint(ssh->kex->hash, ssh->exhash, s->g);
    }
    hash_mpint(ssh->kex->hash, ssh->exhash, s->e);
    hash_mpint(ssh->kex->hash, ssh->exhash, s->f);
    hash_mpint(ssh->kex->hash, ssh->exhash, s->K);
    assert(ssh->kex->hash->hlen <= sizeof(s->exchange_hash));
    ssh->kex->hash->final(ssh->exhash, s->exchange_hash);

    dh_cleanup(ssh->kex_ctx);
    ssh->kex_ctx = NULL;

#if 0
    debug(("Exchange hash is:\n"));
    dmemdump(s->exchange_hash, ssh->kex->hash->hlen);
#endif

    s->hkey = ssh->hostkey->newkey(s->hostkeydata, s->hostkeylen);
    if (!s->hkey ||
	!ssh->hostkey->verifysig(s->hkey, s->sigdata, s->siglen,
				 (char *)s->exchange_hash,
				 ssh->kex->hash->hlen)) {
	bombout(("Server's host key did not match the signature supplied"));
	crStop(0);
    }

    /*
     * Authenticate remote host: verify host key. (We've already
     * checked the signature of the exchange hash.)
5591
5592
5593
5594
5595
5596
5597

5598
5599


5600
5601
5602
5603
5604
5605
5606

    /*
     * The exchange hash from the very first key exchange is also
     * the session id, used in session key construction and
     * authentication.
     */
    if (!s->got_session_id) {

	memcpy(ssh->v2_session_id, s->exchange_hash,
	       sizeof(s->exchange_hash));


	s->got_session_id = TRUE;
    }

    /*
     * Send SSH2_MSG_NEWKEYS.
     */
    s->pktout = ssh2_pkt_init(SSH2_MSG_NEWKEYS);







>


>
>







5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613

    /*
     * The exchange hash from the very first key exchange is also
     * the session id, used in session key construction and
     * authentication.
     */
    if (!s->got_session_id) {
	assert(sizeof(s->exchange_hash) <= sizeof(ssh->v2_session_id));
	memcpy(ssh->v2_session_id, s->exchange_hash,
	       sizeof(s->exchange_hash));
	assert(ssh->v2_session_id_len <= sizeof(ssh->v2_session_id));
	ssh->v2_session_id_len = ssh->kex->hash->hlen;
	s->got_session_id = TRUE;
    }

    /*
     * Send SSH2_MSG_NEWKEYS.
     */
    s->pktout = ssh2_pkt_init(SSH2_MSG_NEWKEYS);
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646

    /*
     * Set IVs on client-to-server keys. Here we use the exchange
     * hash from the _first_ key exchange.
     */
    {
	unsigned char keyspace[40];
	ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'C',keyspace);
	ssh->cscipher->setkey(ssh->cs_cipher_ctx, keyspace);
	ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'A',keyspace);
	ssh->cscipher->setiv(ssh->cs_cipher_ctx, keyspace);
	ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'E',keyspace);
	ssh->csmac->setkey(ssh->cs_mac_ctx, keyspace);
    }

    logeventf(ssh, "Initialised %.200s client->server encryption",
	      ssh->cscipher->text_name);
    logeventf(ssh, "Initialised %.200s client->server MAC algorithm",
	      ssh->csmac->text_name);







|

|

|







5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653

    /*
     * Set IVs on client-to-server keys. Here we use the exchange
     * hash from the _first_ key exchange.
     */
    {
	unsigned char keyspace[40];
	ssh2_mkkey(ssh,s->K,s->exchange_hash,'C',keyspace);
	ssh->cscipher->setkey(ssh->cs_cipher_ctx, keyspace);
	ssh2_mkkey(ssh,s->K,s->exchange_hash,'A',keyspace);
	ssh->cscipher->setiv(ssh->cs_cipher_ctx, keyspace);
	ssh2_mkkey(ssh,s->K,s->exchange_hash,'E',keyspace);
	ssh->csmac->setkey(ssh->cs_mac_ctx, keyspace);
    }

    logeventf(ssh, "Initialised %.200s client->server encryption",
	      ssh->cscipher->text_name);
    logeventf(ssh, "Initialised %.200s client->server MAC algorithm",
	      ssh->csmac->text_name);
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704

    /*
     * Set IVs on server-to-client keys. Here we use the exchange
     * hash from the _first_ key exchange.
     */
    {
	unsigned char keyspace[40];
	ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'D',keyspace);
	ssh->sccipher->setkey(ssh->sc_cipher_ctx, keyspace);
	ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'B',keyspace);
	ssh->sccipher->setiv(ssh->sc_cipher_ctx, keyspace);
	ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'F',keyspace);
	ssh->scmac->setkey(ssh->sc_mac_ctx, keyspace);
    }
    logeventf(ssh, "Initialised %.200s server->client encryption",
	      ssh->sccipher->text_name);
    logeventf(ssh, "Initialised %.200s server->client MAC algorithm",
	      ssh->scmac->text_name);
    if (ssh->sccomp->text_name)







|

|

|







5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711

    /*
     * Set IVs on server-to-client keys. Here we use the exchange
     * hash from the _first_ key exchange.
     */
    {
	unsigned char keyspace[40];
	ssh2_mkkey(ssh,s->K,s->exchange_hash,'D',keyspace);
	ssh->sccipher->setkey(ssh->sc_cipher_ctx, keyspace);
	ssh2_mkkey(ssh,s->K,s->exchange_hash,'B',keyspace);
	ssh->sccipher->setiv(ssh->sc_cipher_ctx, keyspace);
	ssh2_mkkey(ssh,s->K,s->exchange_hash,'F',keyspace);
	ssh->scmac->setkey(ssh->sc_mac_ctx, keyspace);
    }
    logeventf(ssh, "Initialised %.200s server->client encryption",
	      ssh->sccipher->text_name);
    logeventf(ssh, "Initialised %.200s server->client MAC algorithm",
	      ssh->scmac->text_name);
    if (ssh->sccomp->text_name)
6873
6874
6875
6876
6877
6878
6879
6880

6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902

6903
6904
6905
6906
6907
6908
6909
6910
			ssh2_pkt_addstring(s->pktout, "publickey");	/* method */
			ssh2_pkt_addbool(s->pktout, TRUE);
			ssh2_pkt_addstring_start(s->pktout);
			ssh2_pkt_addstring_data(s->pktout, s->alg, s->alglen);
			ssh2_pkt_addstring_start(s->pktout);
			ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen);

			s->siglen = s->pktout->length - 5 + 4 + 20;

                        if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
                            s->siglen -= 4;
			s->len = 1;       /* message type */
			s->len += 4 + s->pklen;	/* key blob */
			s->len += 4 + s->siglen;	/* data to sign */
			s->len += 4;      /* flags */
			s->agentreq = snewn(4 + s->len, char);
			PUT_32BIT(s->agentreq, s->len);
			s->q = s->agentreq + 4;
			*s->q++ = SSH2_AGENTC_SIGN_REQUEST;
			PUT_32BIT(s->q, s->pklen);
			s->q += 4;
			memcpy(s->q, s->pkblob, s->pklen);
			s->q += s->pklen;
			PUT_32BIT(s->q, s->siglen);
			s->q += 4;
			/* Now the data to be signed... */
                        if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
                            PUT_32BIT(s->q, 20);
                            s->q += 4;
                        }
			memcpy(s->q, ssh->v2_session_id, 20);

			s->q += 20;
			memcpy(s->q, s->pktout->data + 5,
			       s->pktout->length - 5);
			s->q += s->pktout->length - 5;
			/* And finally the (zero) flags word. */
			PUT_32BIT(s->q, 0);
			if (!agent_query(s->agentreq, s->len + 4,
					 &vret, &s->retlen,







|
>


















|


|
>
|







6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
			ssh2_pkt_addstring(s->pktout, "publickey");	/* method */
			ssh2_pkt_addbool(s->pktout, TRUE);
			ssh2_pkt_addstring_start(s->pktout);
			ssh2_pkt_addstring_data(s->pktout, s->alg, s->alglen);
			ssh2_pkt_addstring_start(s->pktout);
			ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen);

			s->siglen = s->pktout->length - 5 + 4 +
			    ssh->v2_session_id_len;
                        if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
                            s->siglen -= 4;
			s->len = 1;       /* message type */
			s->len += 4 + s->pklen;	/* key blob */
			s->len += 4 + s->siglen;	/* data to sign */
			s->len += 4;      /* flags */
			s->agentreq = snewn(4 + s->len, char);
			PUT_32BIT(s->agentreq, s->len);
			s->q = s->agentreq + 4;
			*s->q++ = SSH2_AGENTC_SIGN_REQUEST;
			PUT_32BIT(s->q, s->pklen);
			s->q += 4;
			memcpy(s->q, s->pkblob, s->pklen);
			s->q += s->pklen;
			PUT_32BIT(s->q, s->siglen);
			s->q += 4;
			/* Now the data to be signed... */
                        if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
                            PUT_32BIT(s->q, ssh->v2_session_id_len);
                            s->q += 4;
                        }
			memcpy(s->q, ssh->v2_session_id,
			       ssh->v2_session_id_len);
			s->q += ssh->v2_session_id_len;
			memcpy(s->q, s->pktout->data + 5,
			       s->pktout->length - 5);
			s->q += s->pktout->length - 5;
			/* And finally the (zero) flags word. */
			PUT_32BIT(s->q, 0);
			if (!agent_query(s->agentreq, s->len + 4,
					 &vret, &s->retlen,
7192
7193
7194
7195
7196
7197
7198
7199

7200
7201
7202
7203
7204
7205
7206
7207
7208


7209
7210
7211
7212
7213
7214
7215
		     * The data to be signed is:
		     *
		     *   string  session-id
		     *
		     * followed by everything so far placed in the
		     * outgoing packet.
		     */
		    sigdata_len = s->pktout->length - 5 + 4 + 20;

                    if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
                        sigdata_len -= 4;
		    sigdata = snewn(sigdata_len, unsigned char);
                    p = 0;
                    if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
                        PUT_32BIT(sigdata+p, 20);
                        p += 4;
                    }
		    memcpy(sigdata+p, ssh->v2_session_id, 20); p += 20;


		    memcpy(sigdata+p, s->pktout->data + 5,
			   s->pktout->length - 5);
                    p += s->pktout->length - 5;
                    assert(p == sigdata_len);
		    sigblob = key->alg->sign(key->data, (char *)sigdata,
					     sigdata_len, &sigblob_len);
		    ssh2_add_sigblob(ssh, s->pktout, pkblob, pkblob_len,







|
>





|


|
>
>







7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
		     * The data to be signed is:
		     *
		     *   string  session-id
		     *
		     * followed by everything so far placed in the
		     * outgoing packet.
		     */
		    sigdata_len = s->pktout->length - 5 + 4 +
			ssh->v2_session_id_len;
                    if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
                        sigdata_len -= 4;
		    sigdata = snewn(sigdata_len, unsigned char);
                    p = 0;
                    if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
                        PUT_32BIT(sigdata+p, ssh->v2_session_id_len);
                        p += 4;
                    }
		    memcpy(sigdata+p, ssh->v2_session_id,
			   ssh->v2_session_id_len);
		    p += ssh->v2_session_id_len;
		    memcpy(sigdata+p, s->pktout->data + 5,
			   s->pktout->length - 5);
                    p += s->pktout->length - 5;
                    assert(p == sigdata_len);
		    sigblob = key->alg->sign(key->data, (char *)sigdata,
					     sigdata_len, &sigblob_len);
		    ssh2_add_sigblob(ssh, s->pktout, pkblob, pkblob_len,