mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-03-22 14:39:24 -05:00
Pageant server: parse requests using BinarySource.
pageant_handle_msg was _particularly_ full of painful manual packet decoding with error checks at every stage, so it's a great relief to throw it all away and replace it with short sequences of calls to the shiny new API!
This commit is contained in:
parent
e43605ee05
commit
392a8c00f6
335
pageant.c
335
pageant.c
@ -80,7 +80,7 @@ static int cmpkeys_rsa(void *av, void *bv)
|
|||||||
*/
|
*/
|
||||||
static int cmpkeys_ssh2_asymm(void *av, void *bv)
|
static int cmpkeys_ssh2_asymm(void *av, void *bv)
|
||||||
{
|
{
|
||||||
strbuf *ablob = (strbuf *) av;
|
ptrlen *ablob = (ptrlen *) av;
|
||||||
struct ssh2_userkey *b = (struct ssh2_userkey *) bv;
|
struct ssh2_userkey *b = (struct ssh2_userkey *) bv;
|
||||||
strbuf *bblob;
|
strbuf *bblob;
|
||||||
int i, c;
|
int i, c;
|
||||||
@ -93,10 +93,11 @@ static int cmpkeys_ssh2_asymm(void *av, void *bv)
|
|||||||
|
|
||||||
c = 0;
|
c = 0;
|
||||||
for (i = 0; i < ablob->len && i < bblob->len; i++) {
|
for (i = 0; i < ablob->len && i < bblob->len; i++) {
|
||||||
if (ablob->u[i] < bblob->u[i]) {
|
unsigned char abyte = ((unsigned char *)ablob->ptr)[i];
|
||||||
|
if (abyte < bblob->u[i]) {
|
||||||
c = -1;
|
c = -1;
|
||||||
break;
|
break;
|
||||||
} else if (ablob->u[i] > bblob->u[i]) {
|
} else if (abyte > bblob->u[i]) {
|
||||||
c = +1;
|
c = +1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -118,11 +119,14 @@ static int cmpkeys_ssh2(void *av, void *bv)
|
|||||||
{
|
{
|
||||||
struct ssh2_userkey *a = (struct ssh2_userkey *) av;
|
struct ssh2_userkey *a = (struct ssh2_userkey *) av;
|
||||||
strbuf *ablob;
|
strbuf *ablob;
|
||||||
|
ptrlen apl;
|
||||||
int toret;
|
int toret;
|
||||||
|
|
||||||
ablob = strbuf_new();
|
ablob = strbuf_new();
|
||||||
a->alg->public_blob(a->data, BinarySink_UPCAST(ablob));
|
a->alg->public_blob(a->data, BinarySink_UPCAST(ablob));
|
||||||
toret = cmpkeys_ssh2_asymm(ablob, bv);
|
apl.ptr = ablob->u;
|
||||||
|
apl.len = ablob->len;
|
||||||
|
toret = cmpkeys_ssh2_asymm(&apl, bv);
|
||||||
strbuf_free(ablob);
|
strbuf_free(ablob);
|
||||||
return toret;
|
return toret;
|
||||||
}
|
}
|
||||||
@ -178,24 +182,20 @@ static void plog(void *logctx, pageant_logfn_t logfn, const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pageant_handle_msg(BinarySink *bs,
|
void pageant_handle_msg(BinarySink *bs,
|
||||||
const void *msg, int msglen,
|
const void *msgdata, int msglen,
|
||||||
void *logctx, pageant_logfn_t logfn)
|
void *logctx, pageant_logfn_t logfn)
|
||||||
{
|
{
|
||||||
const unsigned char *p = msg;
|
BinarySource msg[1];
|
||||||
const unsigned char *msgend;
|
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
msgend = p + msglen;
|
BinarySource_BARE_INIT(msg, msgdata, msglen);
|
||||||
|
|
||||||
/*
|
type = get_byte(msg);
|
||||||
* Get the message type.
|
if (get_err(msg)) {
|
||||||
*/
|
|
||||||
if (msgend < p+1) {
|
|
||||||
pageant_failure_msg(bs, "message contained no type code",
|
pageant_failure_msg(bs, "message contained no type code",
|
||||||
logctx, logfn);
|
logctx, logfn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
type = *p++;
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SSH1_AGENTC_REQUEST_RSA_IDENTITIES:
|
case SSH1_AGENTC_REQUEST_RSA_IDENTITIES:
|
||||||
@ -253,59 +253,34 @@ void pageant_handle_msg(BinarySink *bs,
|
|||||||
{
|
{
|
||||||
struct RSAKey reqkey, *key;
|
struct RSAKey reqkey, *key;
|
||||||
Bignum challenge, response;
|
Bignum challenge, response;
|
||||||
unsigned char response_source[48], response_md5[16];
|
ptrlen session_id;
|
||||||
|
unsigned response_type;
|
||||||
|
unsigned char response_md5[16];
|
||||||
struct MD5Context md5c;
|
struct MD5Context md5c;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
plog(logctx, logfn, "request: SSH1_AGENTC_RSA_CHALLENGE");
|
plog(logctx, logfn, "request: SSH1_AGENTC_RSA_CHALLENGE");
|
||||||
|
|
||||||
reqkey.exponent = reqkey.modulus = challenge = response = NULL;
|
response = NULL;
|
||||||
|
memset(&reqkey, 0, sizeof(reqkey));
|
||||||
|
|
||||||
p += 4;
|
get_rsa_ssh1_pub(msg, &reqkey, NULL, RSA_SSH1_EXPONENT_FIRST);
|
||||||
i = ssh1_read_bignum(p, msgend - p, &reqkey.exponent);
|
challenge = get_mp_ssh1(msg);
|
||||||
if (i < 0) {
|
session_id = get_data(msg, 16);
|
||||||
pageant_failure_msg(
|
response_type = get_uint32(msg);
|
||||||
bs, "request truncated before key exponent",
|
|
||||||
logctx, logfn);
|
if (get_err(msg)) {
|
||||||
|
pageant_failure_msg(bs, "unable to decode request",
|
||||||
|
logctx, logfn);
|
||||||
goto challenge1_cleanup;
|
goto challenge1_cleanup;
|
||||||
}
|
}
|
||||||
p += i;
|
if (response_type != 1) {
|
||||||
i = ssh1_read_bignum(p, msgend - p, &reqkey.modulus);
|
|
||||||
if (i < 0) {
|
|
||||||
pageant_failure_msg(
|
|
||||||
bs, "request truncated before key modulus",
|
|
||||||
logctx, logfn);
|
|
||||||
goto challenge1_cleanup;
|
|
||||||
}
|
|
||||||
p += i;
|
|
||||||
i = ssh1_read_bignum(p, msgend - p, &challenge);
|
|
||||||
if (i < 0) {
|
|
||||||
pageant_failure_msg(
|
|
||||||
bs, "request truncated before challenge",
|
|
||||||
logctx, logfn);
|
|
||||||
goto challenge1_cleanup;
|
|
||||||
}
|
|
||||||
p += i;
|
|
||||||
if (msgend < p+16) {
|
|
||||||
pageant_failure_msg(
|
|
||||||
bs, "request truncated before session id",
|
|
||||||
logctx, logfn);
|
|
||||||
goto challenge1_cleanup;
|
|
||||||
}
|
|
||||||
memcpy(response_source + 32, p, 16);
|
|
||||||
p += 16;
|
|
||||||
if (msgend < p+4) {
|
|
||||||
pageant_failure_msg(
|
|
||||||
bs, "request truncated before response type",
|
|
||||||
logctx, logfn);
|
|
||||||
goto challenge1_cleanup;
|
|
||||||
}
|
|
||||||
if (GET_32BIT(p) != 1) {
|
|
||||||
pageant_failure_msg(
|
pageant_failure_msg(
|
||||||
bs, "response type other than 1 not supported",
|
bs, "response type other than 1 not supported",
|
||||||
logctx, logfn);
|
logctx, logfn);
|
||||||
goto challenge1_cleanup;
|
goto challenge1_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logfn) {
|
if (logfn) {
|
||||||
char fingerprint[128];
|
char fingerprint[128];
|
||||||
reqkey.comment = NULL;
|
reqkey.comment = NULL;
|
||||||
@ -317,13 +292,12 @@ void pageant_handle_msg(BinarySink *bs,
|
|||||||
goto challenge1_cleanup;
|
goto challenge1_cleanup;
|
||||||
}
|
}
|
||||||
response = rsa_ssh1_decrypt(challenge, key);
|
response = rsa_ssh1_decrypt(challenge, key);
|
||||||
for (i = 0; i < 32; i++)
|
|
||||||
response_source[i] = bignum_byte(response, 31 - i);
|
|
||||||
|
|
||||||
MD5Init(&md5c);
|
MD5Init(&md5c);
|
||||||
put_data(&md5c, response_source, 48);
|
for (i = 0; i < 32; i++)
|
||||||
|
put_byte(&md5c, bignum_byte(response, 31 - i));
|
||||||
|
put_data(&md5c, session_id.ptr, session_id.len);
|
||||||
MD5Final(response_md5, &md5c);
|
MD5Final(response_md5, &md5c);
|
||||||
smemclr(response_source, 48); /* burn the evidence */
|
|
||||||
|
|
||||||
put_byte(bs, SSH1_AGENT_RSA_RESPONSE);
|
put_byte(bs, SSH1_AGENT_RSA_RESPONSE);
|
||||||
put_data(bs, response_md5, 16);
|
put_data(bs, response_md5, 16);
|
||||||
@ -331,10 +305,11 @@ void pageant_handle_msg(BinarySink *bs,
|
|||||||
plog(logctx, logfn, "reply: SSH1_AGENT_RSA_RESPONSE");
|
plog(logctx, logfn, "reply: SSH1_AGENT_RSA_RESPONSE");
|
||||||
|
|
||||||
challenge1_cleanup:
|
challenge1_cleanup:
|
||||||
if (response) freebn(response);
|
if (response)
|
||||||
if (challenge) freebn(challenge);
|
freebn(response);
|
||||||
if (reqkey.exponent) freebn(reqkey.exponent);
|
freebn(challenge);
|
||||||
if (reqkey.modulus) freebn(reqkey.modulus);
|
freebn(reqkey.exponent);
|
||||||
|
freebn(reqkey.modulus);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SSH2_AGENTC_SIGN_REQUEST:
|
case SSH2_AGENTC_SIGN_REQUEST:
|
||||||
@ -345,56 +320,20 @@ void pageant_handle_msg(BinarySink *bs,
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
struct ssh2_userkey *key;
|
struct ssh2_userkey *key;
|
||||||
const void *blobp;
|
ptrlen keyblob, sigdata;
|
||||||
int bloblen;
|
|
||||||
const unsigned char *data;
|
|
||||||
strbuf *signature;
|
strbuf *signature;
|
||||||
int datalen;
|
|
||||||
|
|
||||||
plog(logctx, logfn, "request: SSH2_AGENTC_SIGN_REQUEST");
|
plog(logctx, logfn, "request: SSH2_AGENTC_SIGN_REQUEST");
|
||||||
|
|
||||||
if (msgend < p+4) {
|
keyblob = get_string(msg);
|
||||||
pageant_failure_msg(
|
sigdata = get_string(msg);
|
||||||
bs, "request truncated before public key",
|
|
||||||
logctx, logfn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bloblen = toint(GET_32BIT(p));
|
|
||||||
if (bloblen < 0 || bloblen > msgend - (p+4)) {
|
|
||||||
pageant_failure_msg(
|
|
||||||
bs, "request truncated before public key",
|
|
||||||
logctx, logfn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p += 4;
|
|
||||||
blobp = p;
|
|
||||||
p += bloblen;
|
|
||||||
if (msgend < p+4) {
|
|
||||||
pageant_failure_msg(
|
|
||||||
bs, "request truncated before string to sign",
|
|
||||||
logctx, logfn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
datalen = toint(GET_32BIT(p));
|
|
||||||
p += 4;
|
|
||||||
if (datalen < 0 || datalen > msgend - p) {
|
|
||||||
pageant_failure_msg(
|
|
||||||
bs, "request truncated before string to sign",
|
|
||||||
logctx, logfn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
data = p;
|
|
||||||
if (logfn) {
|
if (logfn) {
|
||||||
char *fingerprint = ssh2_fingerprint_blob(blobp, bloblen);
|
char *fingerprint = ssh2_fingerprint_blob(
|
||||||
|
keyblob.ptr, keyblob.len);
|
||||||
plog(logctx, logfn, "requested key: %s", fingerprint);
|
plog(logctx, logfn, "requested key: %s", fingerprint);
|
||||||
sfree(fingerprint);
|
sfree(fingerprint);
|
||||||
}
|
}
|
||||||
{
|
key = find234(ssh2keys, &keyblob, cmpkeys_ssh2_asymm);
|
||||||
strbuf *blob = strbuf_new();
|
|
||||||
put_data(blob, blobp, bloblen);
|
|
||||||
key = find234(ssh2keys, blob, cmpkeys_ssh2_asymm);
|
|
||||||
strbuf_free(blob);
|
|
||||||
}
|
|
||||||
if (!key) {
|
if (!key) {
|
||||||
pageant_failure_msg(bs, "key not found", logctx, logfn);
|
pageant_failure_msg(bs, "key not found", logctx, logfn);
|
||||||
return;
|
return;
|
||||||
@ -403,7 +342,7 @@ void pageant_handle_msg(BinarySink *bs,
|
|||||||
put_byte(bs, SSH2_AGENT_SIGN_RESPONSE);
|
put_byte(bs, SSH2_AGENT_SIGN_RESPONSE);
|
||||||
|
|
||||||
signature = strbuf_new();
|
signature = strbuf_new();
|
||||||
key->alg->sign(key->data, data, datalen,
|
key->alg->sign(key->data, sigdata.ptr, sigdata.len,
|
||||||
BinarySink_UPCAST(signature));
|
BinarySink_UPCAST(signature));
|
||||||
put_stringsb(bs, signature);
|
put_stringsb(bs, signature);
|
||||||
|
|
||||||
@ -417,88 +356,35 @@ void pageant_handle_msg(BinarySink *bs,
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
struct RSAKey *key;
|
struct RSAKey *key;
|
||||||
char *comment;
|
|
||||||
int n, commentlen;
|
|
||||||
|
|
||||||
plog(logctx, logfn, "request: SSH1_AGENTC_ADD_RSA_IDENTITY");
|
plog(logctx, logfn, "request: SSH1_AGENTC_ADD_RSA_IDENTITY");
|
||||||
|
|
||||||
key = snew(struct RSAKey);
|
key = snew(struct RSAKey);
|
||||||
memset(key, 0, sizeof(struct RSAKey));
|
memset(key, 0, sizeof(struct RSAKey));
|
||||||
|
|
||||||
n = rsa_ssh1_readpub(p, msgend - p, key, NULL,
|
get_rsa_ssh1_pub(msg, key, NULL, RSA_SSH1_MODULUS_FIRST);
|
||||||
RSA_SSH1_MODULUS_FIRST);
|
get_rsa_ssh1_priv(msg, key);
|
||||||
if (n < 0) {
|
|
||||||
pageant_failure_msg(
|
|
||||||
bs, "request truncated before public key",
|
|
||||||
logctx, logfn);
|
|
||||||
goto add1_cleanup;
|
|
||||||
}
|
|
||||||
p += n;
|
|
||||||
|
|
||||||
n = rsa_ssh1_readpriv(p, msgend - p, key);
|
|
||||||
if (n < 0) {
|
|
||||||
pageant_failure_msg(
|
|
||||||
bs, "request truncated before private key",
|
|
||||||
logctx, logfn);
|
|
||||||
goto add1_cleanup;
|
|
||||||
}
|
|
||||||
p += n;
|
|
||||||
|
|
||||||
/* SSH-1 names p and q the other way round, i.e. we have
|
/* SSH-1 names p and q the other way round, i.e. we have
|
||||||
* the inverse of p mod q and not of q mod p. We swap the
|
* the inverse of p mod q and not of q mod p. We swap the
|
||||||
* names, because our internal RSA wants iqmp. */
|
* names, because our internal RSA wants iqmp. */
|
||||||
|
key->iqmp = get_mp_ssh1(msg);
|
||||||
|
key->q = get_mp_ssh1(msg);
|
||||||
|
key->p = get_mp_ssh1(msg);
|
||||||
|
|
||||||
n = ssh1_read_bignum(p, msgend - p, &key->iqmp); /* p^-1 mod q */
|
key->comment = mkstr(get_string(msg));
|
||||||
if (n < 0) {
|
|
||||||
pageant_failure_msg(bs, "request truncated before iqmp",
|
if (get_err(msg)) {
|
||||||
|
pageant_failure_msg(bs, "unable to decode request",
|
||||||
logctx, logfn);
|
logctx, logfn);
|
||||||
goto add1_cleanup;
|
goto add1_cleanup;
|
||||||
}
|
}
|
||||||
p += n;
|
|
||||||
|
|
||||||
n = ssh1_read_bignum(p, msgend - p, &key->q); /* p */
|
|
||||||
if (n < 0) {
|
|
||||||
pageant_failure_msg(bs, "request truncated before p",
|
|
||||||
logctx, logfn);
|
|
||||||
goto add1_cleanup;
|
|
||||||
}
|
|
||||||
p += n;
|
|
||||||
|
|
||||||
n = ssh1_read_bignum(p, msgend - p, &key->p); /* q */
|
|
||||||
if (n < 0) {
|
|
||||||
pageant_failure_msg(
|
|
||||||
bs, "request truncated before q", logctx, logfn);
|
|
||||||
goto add1_cleanup;
|
|
||||||
}
|
|
||||||
p += n;
|
|
||||||
|
|
||||||
if (msgend < p+4) {
|
|
||||||
pageant_failure_msg(
|
|
||||||
bs, "request truncated before key comment",
|
|
||||||
logctx, logfn);
|
|
||||||
goto add1_cleanup;
|
|
||||||
}
|
|
||||||
commentlen = toint(GET_32BIT(p));
|
|
||||||
|
|
||||||
if (commentlen < 0 || commentlen > msgend - p) {
|
|
||||||
pageant_failure_msg(
|
|
||||||
bs, "request truncated before key comment",
|
|
||||||
logctx, logfn);
|
|
||||||
goto add1_cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rsa_verify(key)) {
|
if (!rsa_verify(key)) {
|
||||||
pageant_failure_msg(bs, "key is invalid", logctx, logfn);
|
pageant_failure_msg(bs, "key is invalid", logctx, logfn);
|
||||||
goto add1_cleanup;
|
goto add1_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
comment = snewn(commentlen+1, char);
|
|
||||||
if (comment) {
|
|
||||||
memcpy(comment, p + 4, commentlen);
|
|
||||||
comment[commentlen] = '\0';
|
|
||||||
key->comment = comment;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (logfn) {
|
if (logfn) {
|
||||||
char fingerprint[128];
|
char fingerprint[128];
|
||||||
rsa_fingerprint(fingerprint, sizeof(fingerprint), key);
|
rsa_fingerprint(fingerprint, sizeof(fingerprint), key);
|
||||||
@ -529,73 +415,42 @@ void pageant_handle_msg(BinarySink *bs,
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
struct ssh2_userkey *key = NULL;
|
struct ssh2_userkey *key = NULL;
|
||||||
char *comment;
|
ptrlen alg;
|
||||||
const char *alg;
|
|
||||||
int alglen, commlen;
|
|
||||||
int bloblen;
|
|
||||||
|
|
||||||
plog(logctx, logfn, "request: SSH2_AGENTC_ADD_IDENTITY");
|
plog(logctx, logfn, "request: SSH2_AGENTC_ADD_IDENTITY");
|
||||||
|
|
||||||
if (msgend < p+4) {
|
alg = get_string(msg);
|
||||||
pageant_failure_msg(
|
|
||||||
bs, "request truncated before key algorithm",
|
|
||||||
logctx, logfn);
|
|
||||||
goto add2_cleanup;
|
|
||||||
}
|
|
||||||
alglen = toint(GET_32BIT(p));
|
|
||||||
p += 4;
|
|
||||||
if (alglen < 0 || alglen > msgend - p) {
|
|
||||||
pageant_failure_msg(
|
|
||||||
bs, "request truncated before key algorithm",
|
|
||||||
logctx, logfn);
|
|
||||||
goto add2_cleanup;
|
|
||||||
}
|
|
||||||
alg = (const char *)p;
|
|
||||||
p += alglen;
|
|
||||||
|
|
||||||
key = snew(struct ssh2_userkey);
|
key = snew(struct ssh2_userkey);
|
||||||
key->data = NULL;
|
key->data = NULL;
|
||||||
key->comment = NULL;
|
key->comment = NULL;
|
||||||
key->alg = find_pubkey_alg_len(make_ptrlen(alg, alglen));
|
key->alg = find_pubkey_alg_len(alg);
|
||||||
if (!key->alg) {
|
if (!key->alg) {
|
||||||
pageant_failure_msg(bs, "algorithm unknown", logctx, logfn);
|
pageant_failure_msg(bs, "algorithm unknown", logctx, logfn);
|
||||||
goto add2_cleanup;
|
goto add2_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
bloblen = msgend - p;
|
{
|
||||||
key->data = key->alg->openssh_createkey(key->alg, &p, &bloblen);
|
const unsigned char *p = get_ptr(msg);
|
||||||
|
int len = get_avail(msg);
|
||||||
|
key->data = key->alg->openssh_createkey(key->alg, &p, &len);
|
||||||
|
assert(len >= 0);
|
||||||
|
assert(len < get_avail(msg));
|
||||||
|
msg->pos += get_avail(msg) - len;
|
||||||
|
}
|
||||||
|
|
||||||
if (!key->data) {
|
if (!key->data) {
|
||||||
pageant_failure_msg(bs, "key setup failed", logctx, logfn);
|
pageant_failure_msg(bs, "key setup failed", logctx, logfn);
|
||||||
goto add2_cleanup;
|
goto add2_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
key->comment = mkstr(get_string(msg));
|
||||||
* p has been advanced by openssh_createkey, but
|
|
||||||
* certainly not _beyond_ the end of the buffer.
|
|
||||||
*/
|
|
||||||
assert(p <= msgend);
|
|
||||||
|
|
||||||
if (msgend < p+4) {
|
if (get_err(msg)) {
|
||||||
pageant_failure_msg(
|
pageant_failure_msg(bs, "unable to decode request",
|
||||||
bs, "request truncated before key comment",
|
logctx, logfn);
|
||||||
logctx, logfn);
|
goto add2_cleanup;
|
||||||
goto add2_cleanup;
|
}
|
||||||
}
|
|
||||||
commlen = toint(GET_32BIT(p));
|
|
||||||
p += 4;
|
|
||||||
|
|
||||||
if (commlen < 0 || commlen > msgend - p) {
|
|
||||||
pageant_failure_msg(
|
|
||||||
bs, "request truncated before key comment",
|
|
||||||
logctx, logfn);
|
|
||||||
goto add2_cleanup;
|
|
||||||
}
|
|
||||||
comment = snewn(commlen + 1, char);
|
|
||||||
if (comment) {
|
|
||||||
memcpy(comment, p, commlen);
|
|
||||||
comment[commlen] = '\0';
|
|
||||||
}
|
|
||||||
key->comment = comment;
|
|
||||||
|
|
||||||
if (logfn) {
|
if (logfn) {
|
||||||
char *fingerprint = ssh2_fingerprint(key->alg, key->data);
|
char *fingerprint = ssh2_fingerprint(key->alg, key->data);
|
||||||
@ -634,17 +489,17 @@ void pageant_handle_msg(BinarySink *bs,
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
struct RSAKey reqkey, *key;
|
struct RSAKey reqkey, *key;
|
||||||
int n;
|
|
||||||
|
|
||||||
plog(logctx, logfn, "request: SSH1_AGENTC_REMOVE_RSA_IDENTITY");
|
plog(logctx, logfn, "request: SSH1_AGENTC_REMOVE_RSA_IDENTITY");
|
||||||
|
|
||||||
n = rsa_ssh1_readpub(p, msgend - p, &reqkey, NULL,
|
get_rsa_ssh1_pub(msg, &reqkey, NULL, RSA_SSH1_EXPONENT_FIRST);
|
||||||
RSA_SSH1_EXPONENT_FIRST);
|
|
||||||
if (n < 0) {
|
if (get_err(msg)) {
|
||||||
pageant_failure_msg(
|
pageant_failure_msg(bs, "unable to decode request",
|
||||||
bs, "request truncated before public key",
|
logctx, logfn);
|
||||||
logctx, logfn);
|
freebn(reqkey.exponent);
|
||||||
return;
|
freebn(reqkey.modulus);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logfn) {
|
if (logfn) {
|
||||||
@ -680,41 +535,25 @@ void pageant_handle_msg(BinarySink *bs,
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
struct ssh2_userkey *key;
|
struct ssh2_userkey *key;
|
||||||
const void *blobp;
|
ptrlen blob;
|
||||||
int bloblen;
|
|
||||||
|
|
||||||
plog(logctx, logfn, "request: SSH2_AGENTC_REMOVE_IDENTITY");
|
plog(logctx, logfn, "request: SSH2_AGENTC_REMOVE_IDENTITY");
|
||||||
|
|
||||||
if (msgend < p+4) {
|
blob = get_string(msg);
|
||||||
pageant_failure_msg(
|
|
||||||
bs, "request truncated before public key",
|
|
||||||
logctx, logfn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bloblen = toint(GET_32BIT(p));
|
|
||||||
p += 4;
|
|
||||||
|
|
||||||
if (bloblen < 0 || bloblen > msgend - p) {
|
if (get_err(msg)) {
|
||||||
pageant_failure_msg(
|
pageant_failure_msg(bs, "unable to decode request",
|
||||||
bs, "request truncated before public key",
|
logctx, logfn);
|
||||||
logctx, logfn);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
blobp = p;
|
|
||||||
p += bloblen;
|
|
||||||
|
|
||||||
if (logfn) {
|
if (logfn) {
|
||||||
char *fingerprint = ssh2_fingerprint_blob(blobp, bloblen);
|
char *fingerprint = ssh2_fingerprint_blob(blob.ptr, blob.len);
|
||||||
plog(logctx, logfn, "unwanted key: %s", fingerprint);
|
plog(logctx, logfn, "unwanted key: %s", fingerprint);
|
||||||
sfree(fingerprint);
|
sfree(fingerprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
key = find234(ssh2keys, &blob, cmpkeys_ssh2_asymm);
|
||||||
strbuf *blob = strbuf_new();
|
|
||||||
put_data(blob, blobp, bloblen);
|
|
||||||
key = find234(ssh2keys, blob, cmpkeys_ssh2_asymm);
|
|
||||||
strbuf_free(blob);
|
|
||||||
}
|
|
||||||
if (!key) {
|
if (!key) {
|
||||||
pageant_failure_msg(bs, "key not found", logctx, logfn);
|
pageant_failure_msg(bs, "key not found", logctx, logfn);
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user