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:
@@ -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,
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user