1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-08-08 19:02:07 +03:00

support webauthn-sk-ecdsa-sha2-nistp256 signature

This commit is contained in:
Anders Borum
2022-09-21 13:21:11 +02:00
parent fee76af7a5
commit 7063b745ee
4 changed files with 55 additions and 9 deletions

View File

@@ -360,6 +360,7 @@ typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE
/* flags */ /* flags */
#define LIBSSH2_FLAG_SIGPIPE 1 #define LIBSSH2_FLAG_SIGPIPE 1
#define LIBSSH2_FLAG_COMPRESS 2 #define LIBSSH2_FLAG_COMPRESS 2
#define LIBSSH2_FLAG_WEBAUTHN 4 /* use webauthn for sk-ecdsa signatures */
typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION; typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION;
typedef struct _LIBSSH2_CHANNEL LIBSSH2_CHANNEL; typedef struct _LIBSSH2_CHANNEL LIBSSH2_CHANNEL;
@@ -619,6 +620,10 @@ LIBSSH2_API int libssh2_userauth_banner(LIBSSH2_SESSION* session,
char **banner_out); char **banner_out);
LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session); LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session);
/* return 1 if the given algorithm is part of "server-sigs" extension list. */
LIBSSH2_API int libssh2_session_has_signing_algorithm(LIBSSH2_SESSION * session,
char const* algorithm);
LIBSSH2_API int LIBSSH2_API int
libssh2_userauth_password_ex(LIBSSH2_SESSION *session, libssh2_userauth_password_ex(LIBSSH2_SESSION *session,
const char *username, const char *username,

View File

@@ -588,6 +588,7 @@ struct _LIBSSH2_PUBLICKEY
struct flags { struct flags {
int sigpipe; /* LIBSSH2_FLAG_SIGPIPE */ int sigpipe; /* LIBSSH2_FLAG_SIGPIPE */
int compress; /* LIBSSH2_FLAG_COMPRESS */ int compress; /* LIBSSH2_FLAG_COMPRESS */
int webauthn_sk; /* LIBSSH2_FLAG_WEBAUTHN */
}; };
struct _LIBSSH2_SESSION struct _LIBSSH2_SESSION

View File

@@ -1356,6 +1356,9 @@ libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value)
case LIBSSH2_FLAG_COMPRESS: case LIBSSH2_FLAG_COMPRESS:
session->flag.compress = value; session->flag.compress = value;
break; break;
case LIBSSH2_FLAG_WEBAUTHN:
session->flag.webauthn_sk = value;
break;
default: default:
/* unknown flag */ /* unknown flag */
return LIBSSH2_ERROR_INVAL; return LIBSSH2_ERROR_INVAL;

View File

@@ -549,6 +549,35 @@ libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username,
return rc; return rc;
} }
/* return 1 if the given algorithm is part of "server-sigs" extension list. */
LIBSSH2_API int libssh2_session_has_signing_algorithm(LIBSSH2_SESSION * session,
char const* algorithm) {
if(!session->server_sign_algorithms) return 0;
size_t algorithm_len = strlen(algorithm);
size_t pos = 0;
while(pos < session->server_sign_algorithms_len) {
/* values are comma separated and we locate next boundary */
size_t start = pos;
while(pos < session->server_sign_algorithms_len) {
if(session->server_sign_algorithms[pos] == ',') break;
pos += 1;
}
size_t part_len = pos - start;
if(pos < session->server_sign_algorithms_len) {
pos += 1; /* skip past comma */
}
if(part_len == algorithm_len) {
unsigned char* part = session->server_sign_algorithms + start;
if(memcmp(part, algorithm, algorithm_len) == 0) return 1;
}
}
return 0;
}
/* /*
* upgrade_publickey_method * upgrade_publickey_method
* *
@@ -1243,8 +1272,10 @@ static size_t actual_signature_length(const unsigned char *userauth_pblc_method,
size_t sig_len) { size_t sig_len) {
if(sig_len < 5) return sig_len; if(sig_len < 5) return sig_len;
if(userauth_pblc_method_len == 34 && if((userauth_pblc_method_len == 34 &&
memcmp(userauth_pblc_method, "sk-ecdsa-sha2-nistp256@openssh.com", 34) == 0) { memcmp(userauth_pblc_method, "sk-ecdsa-sha2-nistp256@openssh.com", 34) == 0) ||
(userauth_pblc_method_len == 43 &&
memcmp(userauth_pblc_method, "webauthn-sk-ecdsa-sha2-nistp256@openssh.com", 43) == 0)) {
return sig_len - 5; return sig_len - 5;
} }
@@ -1534,11 +1565,17 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
session->userauth_pblc_method_len, session->userauth_pblc_method_len,
sig_len); sig_len);
_libssh2_store_u32(&s, // sometimes we want a different signature algorithm
4 + session->userauth_pblc_method_len + 4 + char const* signature_algorithm = session->userauth_pblc_method;
sig_len); size_t signature_algorithm_len = session->userauth_pblc_method_len;
_libssh2_store_str(&s, (const char *)session->userauth_pblc_method, if(session->flag.webauthn_sk && signature_algorithm_len == 34 &&
session->userauth_pblc_method_len); memcmp(signature_algorithm, "sk-ecdsa-sha2-nistp256@openssh.com", 34) == 0) {
signature_algorithm = "webauthn-sk-ecdsa-sha2-nistp256@openssh.com";
signature_algorithm_len = 43;
}
_libssh2_store_u32(&s, 4 + signature_algorithm_len + 4 + sig_len);
_libssh2_store_str(&s, signature_algorithm, signature_algorithm_len);
LIBSSH2_FREE(session, session->userauth_pblc_method); LIBSSH2_FREE(session, session->userauth_pblc_method);
session->userauth_pblc_method = NULL; session->userauth_pblc_method = NULL;