Visitar URL original
Legacy Agent support for rsa2 key upgrading/downgrading #659 · willco007/libssh2@7d0c75a · GitHub
Skip to content

Commit 7d0c75a

Browse files
author
Will Cosgrove
committed
Legacy Agent support for rsa2 key upgrading/downgrading libssh2#659
1 parent 50a1262 commit 7d0c75a

3 files changed

Lines changed: 68 additions & 9 deletions

File tree

‎include/libssh2.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ typedef struct _LIBSSH2_POLLFD {
508508
#define LIBSSH2_ERROR_KEYFILE_AUTH_FAILED -48
509509
#define LIBSSH2_ERROR_RANDGEN -49
510510
#define LIBSSH2_ERROR_MISSING_USERAUTH_BANNER -50
511+
#define LIBSSH2_ERROR_ALGO_UNSUPPORTED -51
511512

512513
/* this is a define to provide the old (<= 1.2.7) name */
513514
#define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV

‎src/agent.c‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
377377
struct agent_publickey *identity = agent->identity;
378378
ssize_t len = 1 + 4 + identity->external.blob_len + 4 + data_len + 4;
379379
ssize_t method_len;
380+
unsigned char *method_name;
380381
unsigned char *s;
381382
int rc;
382383
uint32_t sign_flags = 0;
@@ -465,8 +466,38 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
465466
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
466467
goto error;
467468
}
469+
470+
/* method name */
471+
method_name = LIBSSH2_ALLOC(session, method_len);
472+
if(!method_name) {
473+
rc = LIBSSH2_ERROR_ALLOC;
474+
goto error;
475+
}
476+
memcpy(method_name, s, method_len);
468477
s += method_len;
469478

479+
/* check to see if we match requested */
480+
if(method_len == session->userauth_pblc_method_len) {
481+
if(memcmp(method_name, session->userauth_pblc_method, method_len)) {
482+
_libssh2_debug(session,
483+
LIBSSH2_TRACE_KEX,
484+
"Agent sign method %.*s",
485+
method_len, method_name);
486+
487+
rc = LIBSSH2_ERROR_ALGO_UNSUPPORTED;
488+
goto error;
489+
}
490+
}
491+
else {
492+
_libssh2_debug(session,
493+
LIBSSH2_TRACE_KEX,
494+
"Agent sign method %.*s",
495+
method_len, method_name);
496+
497+
rc = LIBSSH2_ERROR_ALGO_UNSUPPORTED;
498+
goto error;
499+
}
500+
470501
/* Read the signature */
471502
len -= 4;
472503
if(len < 0) {
@@ -495,6 +526,8 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
495526
LIBSSH2_FREE(session, transctx->response);
496527
transctx->response = NULL;
497528

529+
transctx->state = agent_NB_state_init;
530+
498531
return _libssh2_error(session, rc, "agent sign failure");
499532
}
500533

‎src/userauth.c‎

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,9 +1283,6 @@ _libssh2_key_sign_algorithm(LIBSSH2_SESSION *session,
12831283
if(key_method) {
12841284
memcpy(*key_method, match, match_len);
12851285
*key_method_len = match_len;
1286-
1287-
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
1288-
"Signing using %.*s", match_len, match);
12891286
}
12901287
else {
12911288
*key_method_len = 0;
@@ -1321,6 +1318,10 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
13211318
};
13221319
int rc;
13231320
unsigned char *s;
1321+
int auth_attempts = 0;
1322+
1323+
retry_auth:
1324+
auth_attempts++;
13241325

13251326
if(session->userauth_pblc_state == libssh2_NB_state_idle) {
13261327

@@ -1364,13 +1365,26 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
13641365
session->userauth_pblc_method_len);
13651366
}
13661367

1367-
/* upgrade key key signing algo needed */
1368-
rc = _libssh2_key_sign_algorithm(session,
1369-
&session->userauth_pblc_method,
1370-
&session->userauth_pblc_method_len);
1368+
/* upgrade key signing algo if it is supported and
1369+
* it is our first auth attempt, otherwise fallback to
1370+
* the key default algo */
1371+
if(auth_attempts == 1) {
1372+
rc = _libssh2_key_sign_algorithm(session,
1373+
&session->userauth_pblc_method,
1374+
&session->userauth_pblc_method_len);
13711375

1372-
if(rc)
1373-
return rc;
1376+
if(rc)
1377+
return rc;
1378+
}
1379+
1380+
if(session->userauth_pblc_method_len &&
1381+
session->userauth_pblc_method) {
1382+
_libssh2_debug(session,
1383+
LIBSSH2_TRACE_KEX,
1384+
"Signing using %.*s",
1385+
session->userauth_pblc_method_len,
1386+
session->userauth_pblc_method);
1387+
}
13741388

13751389
/*
13761390
* 45 = packet_type(1) + username_len(4) + servicename_len(4) +
@@ -1528,6 +1542,17 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
15281542
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
15291543
"Would block");
15301544
}
1545+
else if(rc == LIBSSH2_ERROR_ALGO_UNSUPPORTED && auth_attempts == 1) {
1546+
/* try again with the default key algo */
1547+
LIBSSH2_FREE(session, session->userauth_pblc_method);
1548+
session->userauth_pblc_method = NULL;
1549+
LIBSSH2_FREE(session, session->userauth_pblc_packet);
1550+
session->userauth_pblc_packet = NULL;
1551+
session->userauth_pblc_state = libssh2_NB_state_idle;
1552+
1553+
rc = LIBSSH2_ERROR_NONE;
1554+
goto retry_auth;
1555+
}
15311556
else if(rc) {
15321557
LIBSSH2_FREE(session, session->userauth_pblc_method);
15331558
session->userauth_pblc_method = NULL;

0 commit comments

Comments
 (0)