libssh2_userauth_publickey_sk(3)

πŸ“¦
version 1.11.1 Β· 2 versions
  • 1.11.1 Β· alpine 3.22, alpine 3.23, alpine 3.24, arch rolling, debian trixie, epel 10, epel 9, fedora 43, fedora 44, opensuse-leap 16.0, ubuntu questing, ubuntu resolute, ubuntu stonking (latest)
  • 1.11.0 Β· ubuntu noble
, in alpine 3.22, alpine 3.23, alpine 3.24, arch rolling, debian trixie, epel 10, epel 9, fedora 43, fedora 44, opensuse-leap 16.0, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ’– 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 from libssh2_session_init_ex(3).
  • username β€” the name of the user you're trying to authenticate as.
  • username_len β€” length of the username parameter.
  • publickeydata β€” buffer holding the contents of a public key file. If it's NULL, the public key gets extracted from privatekeydata instead. 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 by libssh2_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 the data parameter.
  • algorithm β€” the signing algorithm to use. possible values are LIBSSH2_HOSTKEY_TYPE_ED25519 and LIBSSH2_HOSTKEY_TYPE_ECDSA_256.
  • flags β€” a bitmask specifying options for the authenticator. When LIBSSH2_SK_PRESENCE_REQUIRED is set, the authenticator requires a touch. When LIBSSH2_SK_VERIFICATION_REQUIRED is set, the authenticator requires a PIN. And fr fr: many servers and authenticators do not work properly when LIBSSH2_SK_PRESENCE_REQUIRED is 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 the key_handle parameter.
  • 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 the flags parameter 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 the r component of the signature in a big-endian binary representation. For both algorithms, use LIBSSH2_ALLOC to allocate the memory. It will be freed by the caller.
  • sig_r_len β€” the length of the sig_r parameter.
  • sig_s β€” for ECDSA signatures, this contains the s component of the signature in a big-endian binary representation. Use LIBSSH2_ALLOC to allocate the memory. It will be freed by the caller. For Ed25519 signatures, set this to NULL.
  • sig_s_len β€” the length of the sig_s parameter.

⭐ 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 πŸŒΈβœ¨πŸŽ€