libssh2_userauth_publickey_sk(3)
π libssh2_userauth_publickey_sk π
okay bestie, so this is a page from the libssh2 manual β like, the libssh2_userauth_publickey_sk one β and it's all about logging in with your little FIDO2 key fob thing. security key girlies rise π«Ά
β¨ NAME β¨
libssh2_userauth_publickey_sk β authenticate a session with a FIDO2 authenticator
β¨ SYNOPSIS β¨
#include <libssh2.h>
int
libssh2_userauth_publickey_sk(LIBSSH2_SESSION *session,
const char *username,
size_t username_len,
const unsigned char *publickeydata,
size_t publickeydata_len,
const char *privatekeydata,
size_t privatekeydata_len,
const char *passphrase,
LIBSSH2_USERAUTH_SK_SIGN_FUNC((*sign_callback)),
void **abstract);
π CALLBACK π
here's the little callback contract, she's giving very much "define your own function" energy π
#define LIBSSH2_SK_PRESENCE_REQUIRED 0x01
#define LIBSSH2_SK_VERIFICATION_REQUIRED 0x04
typedef struct _LIBSSH2_SK_SIG_INFO {
uint8_t flags;
uint32_t counter;
unsigned char *sig_r;
size_t sig_r_len;
unsigned char *sig_s;
size_t sig_s_len;
} LIBSSH2_SK_SIG_INFO;
int name(LIBSSH2_SESSION *session, LIBSSH2_SK_SIG_INFO *sig_info,
const unsigned char *data, size_t data_len, int algorithm,
uint8_t flags, const char *application,
const unsigned char *key_handle, size_t handle_len,
void **abstract);
πΈ DESCRIPTION πΈ
okay so here's the rundown of every single parameter, no skipping, we're thorough in this house β¨
sessionβ the Session instance you got back fromlibssh2_session_init_ex(3).usernameβ the name of the user you're trying to authenticate as.username_lenβ length of theusernameparameter.publickeydataβ buffer holding the contents of a public key file. If it'sNULL, the public key gets extracted fromprivatekeydatainstead. And when you're doing certificate authentication, this buffer should hold the public certificate data.publickeydata_lenβ length of the public key data.privatekeydataβ buffer holding the contents of a private key file.privatekeydata_lenβ length of the private key data.passphraseβ the passphrase used when decoding the private key file.sign_callbackβ the callback that talks to your FIDO2 authenticator.abstractβ user-provided data that gets passed along to the callback.
So what does it do? It attempts FIDO2 authentication, using either the sk-ssh-ed25519@openssh.com or sk-ecdsa-sha2-nistp256@openssh.com key exchange algorithms. iconic behaviour honestly.
π¨ heads up bestie: this function is only supported when libssh2 is backed by OpenSSL. no OpenSSL, no vibes.
π CALLBACK DESCRIPTION π
now the callback's own little parameter list, because she has lore:
sessionβ the Session instance as returned bylibssh2_session_init_ex(3).sig_infoβ filled in by the callback with the signature and the accompanying information from the authenticator.dataβ the data to sign.data_lenβ the length of thedataparameter.algorithmβ the signing algorithm to use. possible values areLIBSSH2_HOSTKEY_TYPE_ED25519andLIBSSH2_HOSTKEY_TYPE_ECDSA_256.flagsβ a bitmask specifying options for the authenticator. WhenLIBSSH2_SK_PRESENCE_REQUIREDis set, the authenticator requires a touch. WhenLIBSSH2_SK_VERIFICATION_REQUIREDis set, the authenticator requires a PIN. And fr fr: many servers and authenticators do not work properly whenLIBSSH2_SK_PRESENCE_REQUIREDis not set. so like, set it. πapplicationβ a user-defined string used as the RP name for the authenticator. usually"ssh:".key_handleβ the key handle to use for the authenticator's allow list.handle_lenβ the length of thekey_handleparameter.abstractβ user-defined data. when a PIN is required, use this to pass in the PIN, or a function pointer to retrieve the PIN.
The sign_callback is the one responsible for communicating with the hardware authenticator to generate a signature. On success, the signature information must be placed in the sig_info parameter and the callback must return 0. On failure, it should return a negative number. no pressure though π
π¦ the fields of LIBSSH2_SK_SIG_INFO π¦
she's got layers, let's go field by field:
flagsβ a bitmask specifying options for the authenticator. This should be read from the authenticator and not merely copied from theflagsparameter to the callback. (yes that's a real instruction, don't be lazy π)counterβ a value returned from the authenticator.sig_rβ for Ed25519 signatures, this contains the entire signature, as returned directly from the authenticator. For ECDSA signatures, this contains thercomponent of the signature in a big-endian binary representation. For both algorithms, useLIBSSH2_ALLOCto allocate the memory. It will be freed by the caller.sig_r_lenβ the length of thesig_rparameter.sig_sβ for ECDSA signatures, this contains thescomponent of the signature in a big-endian binary representation. UseLIBSSH2_ALLOCto allocate the memory. It will be freed by the caller. For Ed25519 signatures, set this toNULL.sig_s_lenβ the length of thesig_sparameter.
β RETURN VALUE β
Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. And listen β while LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. she's just saying "not right now bestie", it's a whole different vibe. π«Ά
π ERRORS π
some of the errors this function may return include:
LIBSSH2_ERROR_ALLOCβ an internal memory allocation call failed.LIBSSH2_ERROR_SOCKET_SENDβ unable to send data on socket.LIBSSH2_ERROR_AUTHENTICATION_FAILEDβ failed, invalid username/key.
π AVAILABILITY π
Added in libssh2 1.10.0.
π SEE ALSO π
and that's the whole page, periodt π this was libssh2, version 1.10.0, dated 1 Jun 2022 β go forth and authenticate with your little key fob, you absolute main character πΈβ¨π
π¦ where this page comes from
- alpine 3.22: libssh2-doc 1.11.1-r3 Β· BSD-3-Clause
- alpine 3.23: libssh2-doc 1.11.1-r4 Β· BSD-3-Clause
- alpine 3.24: libssh2-doc 1.11.1-r4 Β· BSD-3-Clause
- arch rolling: libssh2 1.11.1-7 Β· BSD-3-Clause
- debian trixie: libssh2-1-dev 1.11.1-1+deb13u1 Β· BSD3
- debian trixie: libssh2-1-dev 1.11.1-1+deb13u2 Β· BSD3
- epel 10: libssh2-docs 1.11.1-9.el10_3 Β· BSD-3-Clause
- epel 9: libssh2-docs 1.11.1-9.el9 Β· BSD-3-Clause
- fedora 43: libssh2-docs 1.11.1-4.fc43 Β· BSD-3-Clause
- fedora 43: libssh2-docs 1.11.1-9.fc43 Β· BSD-3-Clause
- fedora 44: libssh2-docs 1.11.1-5.fc44 Β· BSD-3-Clause
- fedora 44: libssh2-docs 1.11.1-9.fc44 Β· BSD-3-Clause
- opensuse-leap 16.0: libssh2-devel 1.11.1-160000.5.1 Β· BSD-3-Clause
- opensuse-leap 16.0: libssh2-devel 1.11.1-160000.5.1 Β· BSD-3-Clause
- opensuse-leap 16.0: libssh2-devel 1.11.1-160000.5.1 Β· BSD-3-Clause
- opensuse-leap 16.0: libssh2-devel 1.11.1-160000.5.1 Β· BSD-3-Clause
- ubuntu questing: libssh2-1-dev 1.11.1-1build1
- ubuntu questing: libssh2-1-dev 1.11.1-1ubuntu0.25.10.2
- ubuntu resolute: libssh2-1-dev 1.11.1-1build2 Β· BSD3
- ubuntu resolute: libssh2-1-dev 1.11.1-1ubuntu0.26.04.4 Β· BSD3
- ubuntu stonking: libssh2-1-dev 1.11.1-6 Β· BSD3
- π the page's license: BSD-3-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms