version 1.14, 2020/01/06 02:39:30 |
version 1.15, 2020/01/25 23:13:09 |
|
|
#include <fido/credman.h> |
#include <fido/credman.h> |
|
|
#ifndef SK_STANDALONE |
#ifndef SK_STANDALONE |
#include "log.h" |
# include "log.h" |
#include "xmalloc.h" |
# include "xmalloc.h" |
#endif |
/* |
|
* If building as part of OpenSSH, then rename exported functions. |
|
* This must be done before including sk-api.h. |
|
*/ |
|
# define sk_api_version ssh_sk_api_version |
|
# define sk_enroll ssh_sk_enroll |
|
# define sk_sign ssh_sk_sign |
|
# define sk_load_resident_keys ssh_sk_load_resident_keys |
|
#endif /* !SK_STANDALONE */ |
|
|
|
#include "sk-api.h" |
|
|
/* #define SK_DEBUG 1 */ |
/* #define SK_DEBUG 1 */ |
|
|
#define MAX_FIDO_DEVICES 256 |
#define MAX_FIDO_DEVICES 256 |
|
|
} while (0) |
} while (0) |
#endif |
#endif |
|
|
#define SK_VERSION_MAJOR 0x00040000 /* current API version */ |
|
|
|
/* Flags */ |
|
#define SK_USER_PRESENCE_REQD 0x01 |
|
#define SK_USER_VERIFICATION_REQD 0x04 |
|
#define SK_RESIDENT_KEY 0x20 |
|
|
|
/* Algs */ |
|
#define SK_ECDSA 0x00 |
|
#define SK_ED25519 0x01 |
|
|
|
/* Error codes */ |
|
#define SSH_SK_ERR_GENERAL -1 |
|
#define SSH_SK_ERR_UNSUPPORTED -2 |
|
#define SSH_SK_ERR_PIN_REQUIRED -3 |
|
|
|
struct sk_enroll_response { |
|
uint8_t *public_key; |
|
size_t public_key_len; |
|
uint8_t *key_handle; |
|
size_t key_handle_len; |
|
uint8_t *signature; |
|
size_t signature_len; |
|
uint8_t *attestation_cert; |
|
size_t attestation_cert_len; |
|
}; |
|
|
|
struct sk_sign_response { |
|
uint8_t flags; |
|
uint32_t counter; |
|
uint8_t *sig_r; |
|
size_t sig_r_len; |
|
uint8_t *sig_s; |
|
size_t sig_s_len; |
|
}; |
|
|
|
struct sk_resident_key { |
|
uint32_t alg; |
|
size_t slot; |
|
char *application; |
|
struct sk_enroll_response key; |
|
}; |
|
|
|
struct sk_option { |
|
char *name; |
|
char *value; |
|
uint8_t required; |
|
}; |
|
|
|
/* If building as part of OpenSSH, then rename exported functions */ |
|
#if !defined(SK_STANDALONE) |
|
#define sk_api_version ssh_sk_api_version |
|
#define sk_enroll ssh_sk_enroll |
|
#define sk_sign ssh_sk_sign |
|
#define sk_load_resident_keys ssh_sk_load_resident_keys |
|
#endif |
|
|
|
/* Return the version of the middleware API */ |
/* Return the version of the middleware API */ |
uint32_t sk_api_version(void); |
uint32_t sk_api_version(void); |
|
|
|
|
uint32_t |
uint32_t |
sk_api_version(void) |
sk_api_version(void) |
{ |
{ |
return SK_VERSION_MAJOR; |
return SSH_SK_VERSION_MAJOR; |
} |
} |
|
|
/* Select the first identified FIDO device attached to the system */ |
/* Select the first identified FIDO device attached to the system */ |
|
|
{ |
{ |
switch(alg) { |
switch(alg) { |
#ifdef WITH_OPENSSL |
#ifdef WITH_OPENSSL |
case SK_ECDSA: |
case SSH_SK_ECDSA: |
return pack_public_key_ecdsa(cred, response); |
return pack_public_key_ecdsa(cred, response); |
#endif /* WITH_OPENSSL */ |
#endif /* WITH_OPENSSL */ |
case SK_ED25519: |
case SSH_SK_ED25519: |
return pack_public_key_ed25519(cred, response); |
return pack_public_key_ed25519(cred, response); |
default: |
default: |
return -1; |
return -1; |
|
|
{ |
{ |
switch (fidoerr) { |
switch (fidoerr) { |
case FIDO_ERR_UNSUPPORTED_OPTION: |
case FIDO_ERR_UNSUPPORTED_OPTION: |
|
case FIDO_ERR_UNSUPPORTED_ALGORITHM: |
return SSH_SK_ERR_UNSUPPORTED; |
return SSH_SK_ERR_UNSUPPORTED; |
case FIDO_ERR_PIN_REQUIRED: |
case FIDO_ERR_PIN_REQUIRED: |
case FIDO_ERR_PIN_INVALID: |
case FIDO_ERR_PIN_INVALID: |
|
|
*enroll_response = NULL; |
*enroll_response = NULL; |
switch(alg) { |
switch(alg) { |
#ifdef WITH_OPENSSL |
#ifdef WITH_OPENSSL |
case SK_ECDSA: |
case SSH_SK_ECDSA: |
cose_alg = COSE_ES256; |
cose_alg = COSE_ES256; |
break; |
break; |
#endif /* WITH_OPENSSL */ |
#endif /* WITH_OPENSSL */ |
case SK_ED25519: |
case SSH_SK_ED25519: |
cose_alg = COSE_EDDSA; |
cose_alg = COSE_EDDSA; |
break; |
break; |
default: |
default: |
|
|
goto out; |
goto out; |
} |
} |
if (device == NULL && (device = pick_first_device()) == NULL) { |
if (device == NULL && (device = pick_first_device()) == NULL) { |
|
ret = SSH_SK_ERR_DEVICE_NOT_FOUND; |
skdebug(__func__, "pick_first_device failed"); |
skdebug(__func__, "pick_first_device failed"); |
goto out; |
goto out; |
} |
} |
|
|
fido_strerr(r)); |
fido_strerr(r)); |
goto out; |
goto out; |
} |
} |
if ((r = fido_cred_set_rk(cred, (flags & SK_RESIDENT_KEY) != 0 ? |
if ((r = fido_cred_set_rk(cred, (flags & SSH_SK_RESIDENT_KEY) != 0 ? |
FIDO_OPT_TRUE : FIDO_OPT_OMIT)) != FIDO_OK) { |
FIDO_OPT_TRUE : FIDO_OPT_OMIT)) != FIDO_OK) { |
skdebug(__func__, "fido_cred_set_rk: %s", fido_strerr(r)); |
skdebug(__func__, "fido_cred_set_rk: %s", fido_strerr(r)); |
goto out; |
goto out; |
|
|
{ |
{ |
switch(alg) { |
switch(alg) { |
#ifdef WITH_OPENSSL |
#ifdef WITH_OPENSSL |
case SK_ECDSA: |
case SSH_SK_ECDSA: |
return pack_sig_ecdsa(assert, response); |
return pack_sig_ecdsa(assert, response); |
#endif /* WITH_OPENSSL */ |
#endif /* WITH_OPENSSL */ |
case SK_ED25519: |
case SSH_SK_ED25519: |
return pack_sig_ed25519(assert, response); |
return pack_sig_ed25519(assert, response); |
default: |
default: |
return -1; |
return -1; |
|
|
goto out; |
goto out; |
} |
} |
if ((r = fido_assert_set_up(assert, |
if ((r = fido_assert_set_up(assert, |
(flags & SK_USER_PRESENCE_REQD) ? |
(flags & SSH_SK_USER_PRESENCE_REQD) ? |
FIDO_OPT_TRUE : FIDO_OPT_FALSE)) != FIDO_OK) { |
FIDO_OPT_TRUE : FIDO_OPT_FALSE)) != FIDO_OK) { |
skdebug(__func__, "fido_assert_set_up: %s", fido_strerr(r)); |
skdebug(__func__, "fido_assert_set_up: %s", fido_strerr(r)); |
goto out; |
goto out; |
|
|
|
|
switch (fido_cred_type(cred)) { |
switch (fido_cred_type(cred)) { |
case COSE_ES256: |
case COSE_ES256: |
srk->alg = SK_ECDSA; |
srk->alg = SSH_SK_ECDSA; |
break; |
break; |
case COSE_EDDSA: |
case COSE_EDDSA: |
srk->alg = SK_ED25519; |
srk->alg = SSH_SK_ED25519; |
break; |
break; |
default: |
default: |
skdebug(__func__, "unsupported key type %d", |
skdebug(__func__, "unsupported key type %d", |
fido_cred_type(cred)); |
fido_cred_type(cred)); |
goto out; |
goto out; /* XXX free rk and continue */ |
} |
} |
|
|
if ((r = pack_public_key(srk->alg, cred, |
if ((r = pack_public_key(srk->alg, cred, |