summaryrefslogtreecommitdiffstats
path: root/src/util
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2016-09-23 17:11:35 +0200
committerJakub Hrozek <jhrozek@redhat.com>2017-02-23 10:15:04 +0100
commitdd17a3aaddab6f122dff3bd15b7005464c07c0ea (patch)
tree2789a97339b086c74c0b01610cca3f7b7a374b7b /src/util
parentf70d946f8cde55b6bdc09345e22849842bca4387 (diff)
downloadsssd-dd17a3aaddab6f122dff3bd15b7005464c07c0ea.tar.gz
sssd-dd17a3aaddab6f122dff3bd15b7005464c07c0ea.tar.xz
sssd-dd17a3aaddab6f122dff3bd15b7005464c07c0ea.zip
authtok: enhance support for Smartcard auth blobs
The blobs contains beside the PIN the name of the PKCS#11 module and the token name where the certificate of the user was found and the key id. Those data will be used e.g. by the pkinit module to make sure them right certificate is used. Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Diffstat (limited to 'src/util')
-rw-r--r--src/util/authtok-utils.c91
-rw-r--r--src/util/authtok-utils.h56
-rw-r--r--src/util/authtok.c320
-rw-r--r--src/util/authtok.h84
4 files changed, 540 insertions, 11 deletions
diff --git a/src/util/authtok-utils.c b/src/util/authtok-utils.c
index 65fba9022..e7123df34 100644
--- a/src/util/authtok-utils.c
+++ b/src/util/authtok-utils.c
@@ -72,3 +72,94 @@ errno_t sss_auth_pack_2fa_blob(const char *fa1, size_t fa1_len,
return 0;
}
+
+errno_t sss_auth_pack_sc_blob(const char *pin, size_t pin_len,
+ const char *token_name, size_t token_name_len,
+ const char *module_name, size_t module_name_len,
+ const char *key_id, size_t key_id_len,
+ uint8_t *buf, size_t buf_len,
+ size_t *_sc_blob_len)
+{
+ size_t c;
+ uint32_t tmp_uint32_t;
+
+ if (pin_len > UINT32_MAX || token_name_len > UINT32_MAX
+ || module_name_len > UINT32_MAX
+ || (pin_len != 0 && pin == NULL)
+ || (token_name_len != 0 && token_name == NULL)
+ || (module_name_len != 0 && module_name == NULL)
+ || (key_id_len != 0 && key_id == NULL)) {
+ return EINVAL;
+ }
+
+ /* A missing pin is ok in the case of a reader with a keyboard */
+ if (pin == NULL) {
+ pin = "";
+ pin_len = 0;
+ }
+
+ if (token_name == NULL) {
+ token_name = "";
+ token_name_len = 0;
+ }
+
+ if (module_name == NULL) {
+ module_name = "";
+ module_name_len = 0;
+ }
+
+ if (key_id == NULL) {
+ key_id = "";
+ key_id_len = 0;
+ }
+
+ /* len should not include the trailing \0 */
+ if (pin_len == 0 || pin[pin_len - 1] == '\0') {
+ pin_len = strlen(pin);
+ }
+
+ if (token_name_len == 0 || token_name[token_name_len - 1] == '\0') {
+ token_name_len = strlen(token_name);
+ }
+
+ if (module_name_len == 0 || module_name[module_name_len - 1] == '\0') {
+ module_name_len = strlen(module_name);
+ }
+
+ if (key_id_len == 0 || key_id[key_id_len - 1] == '\0') {
+ key_id_len = strlen(key_id);
+ }
+
+ *_sc_blob_len = pin_len + token_name_len + module_name_len + key_id_len + 4
+ + 4 * sizeof(uint32_t);
+ if (buf == NULL || buf_len < *_sc_blob_len) {
+ return EAGAIN;
+ }
+
+ c = 0;
+ tmp_uint32_t = (uint32_t) pin_len + 1;
+ SAFEALIGN_COPY_UINT32(buf, &tmp_uint32_t, &c);
+ tmp_uint32_t = (uint32_t) token_name_len + 1;
+ SAFEALIGN_COPY_UINT32(buf + c, &tmp_uint32_t, &c);
+ tmp_uint32_t = (uint32_t) module_name_len + 1;
+ SAFEALIGN_COPY_UINT32(buf + c, &tmp_uint32_t, &c);
+ tmp_uint32_t = (uint32_t) key_id_len + 1;
+ SAFEALIGN_COPY_UINT32(buf + c, &tmp_uint32_t, &c);
+
+ memcpy(buf + c, pin, pin_len);
+ buf[c + pin_len] = '\0';
+ c += pin_len + 1;
+
+ memcpy(buf + c, token_name, token_name_len);
+ buf[c + token_name_len] = '\0';
+ c += token_name_len + 1;
+
+ memcpy(buf + c, module_name, module_name_len);
+ buf[c + module_name_len] = '\0';
+ c += module_name_len + 1;
+
+ memcpy(buf + c, key_id, key_id_len);
+ buf[c + key_id_len] = '\0';
+
+ return 0;
+}
diff --git a/src/util/authtok-utils.h b/src/util/authtok-utils.h
index 07aef3c18..c5aace39f 100644
--- a/src/util/authtok-utils.h
+++ b/src/util/authtok-utils.h
@@ -25,6 +25,37 @@
#include "sss_client/sss_cli.h"
/**
+ * @brief Fill memory buffer with Smartcard authentication blob
+ *
+ * @param[in] pin PIN, null terminated
+ * @param[in] pin_len Length of the PIN, if 0
+ * strlen() will be called internally
+ * @param[in] token_name Token name, null terminated
+ * @param[in] token_name_len Length of the token name, if 0
+ * strlen() will be called internally
+ * @param[in] module_name Name of PKCS#11 module, null terminated
+ * @param[in] module_name_len Length of the module name, if 0
+ * strlen() will be called internally
+ * @param[in] key_id Key ID of the certificate
+ * @param[in] key_id_len Length of the key id of the certificate, if 0
+ * strlen() will be called internally
+ * @param[in] buf memory buffer of size buf_len, may be NULL
+ * @param[in] buf_len size of memory buffer buf
+ *
+ * @param[out] _sc_blob len size of the Smartcard authentication blob
+ *
+ * @return EOK on success
+ * EINVAL if input data is not consistent
+ * EAGAIN if provided buffer is too small, _sc_blob_len
+ * contains the size needed to store the SC blob
+ */
+errno_t sss_auth_pack_sc_blob(const char *pin, size_t pin_len,
+ const char *token_name, size_t token_name_len,
+ const char *module_name, size_t module_name_len,
+ const char *key_id, size_t key_id_len,
+ uint8_t *buf, size_t buf_len,
+ size_t *_sc_blob_len);
+/**
* @brief Fill memory buffer with 2FA blob
*
* @param[in] fa1 First authentication factor, null terminated
@@ -67,4 +98,29 @@ errno_t sss_auth_unpack_2fa_blob(TALLOC_CTX *mem_ctx,
const uint8_t *blob, size_t blob_len,
char **fa1, size_t *_fa1_len,
char **fa2, size_t *_fa2_len);
+
+/**
+ * @brief Extract SC data from memory buffer
+ *
+ * @param[in] mem_ctx Talloc memory context to allocate the 2FA
+ * data on
+ * @param[in] blob Memory buffer containing the 2FA data
+ * @param[in] blob_len Size of the memory buffer
+ * @param[out] _pin PIN, null terminated
+ * @param[out] _pin_len Length of the PIN
+ * @param[out] _token_name Token name, null terminated
+ * @param[out] _token_name_len Length of the token name
+ * @param[out] _module_name Name of PKCS#11 module, null terminated
+ * @param[out] _module_name_len Length of the module name
+ *
+ * @return EOK on success
+ * EINVAL if input data is not consistent
+ * EINVAL if no memory can be allocated
+ */
+errno_t sss_auth_unpack_sc_blob(TALLOC_CTX *mem_ctx,
+ const uint8_t *blob, size_t blob_len,
+ char **pin, size_t *_pin_len,
+ char **token_name, size_t *_token_name_len,
+ char **module_name, size_t *_module_name_len,
+ char **key_id, size_t *_key_id_len);
#endif /* __AUTHTOK_UTILS_H__ */
diff --git a/src/util/authtok.c b/src/util/authtok.c
index 6062cd875..c2f78be32 100644
--- a/src/util/authtok.c
+++ b/src/util/authtok.c
@@ -196,10 +196,9 @@ errno_t sss_authtok_set(struct sss_auth_token *tok,
case SSS_AUTHTOK_TYPE_2FA:
return sss_authtok_set_2fa_from_blob(tok, data, len);
case SSS_AUTHTOK_TYPE_SC_PIN:
- return sss_authtok_set_sc_pin(tok, (const char*)data, len);
+ return sss_authtok_set_sc_from_blob(tok, data, len);
case SSS_AUTHTOK_TYPE_SC_KEYPAD:
- sss_authtok_set_sc_keypad(tok);
- return EOK;
+ return sss_authtok_set_sc_from_blob(tok, data, len);
case SSS_AUTHTOK_TYPE_EMPTY:
sss_authtok_set_empty(tok);
return EOK;
@@ -425,6 +424,104 @@ errno_t sss_authtok_set_2fa(struct sss_auth_token *tok,
return EOK;
}
+errno_t sss_authtok_set_sc(struct sss_auth_token *tok,
+ enum sss_authtok_type type,
+ const char *pin, size_t pin_len,
+ const char *token_name, size_t token_name_len,
+ const char *module_name, size_t module_name_len,
+ const char *key_id, size_t key_id_len)
+{
+ int ret;
+ size_t needed_size;
+
+ if (type != SSS_AUTHTOK_TYPE_SC_PIN
+ && type != SSS_AUTHTOK_TYPE_SC_KEYPAD) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid type [%d].\n", type);
+ return EINVAL;
+ }
+
+ sss_authtok_set_empty(tok);
+
+ ret = sss_auth_pack_sc_blob(pin, pin_len, token_name, token_name_len,
+ module_name, module_name_len,
+ key_id, key_id_len, NULL, 0,
+ &needed_size);
+ if (ret != EAGAIN) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_auth_pack_sc_blob failed.\n");
+ return ret;
+ }
+
+ tok->data = talloc_size(tok, needed_size);
+ if (tok->data == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n");
+ return ENOMEM;
+ }
+
+ ret = sss_auth_pack_sc_blob(pin, pin_len, token_name, token_name_len,
+ module_name, module_name_len,
+ key_id, key_id_len, tok->data,
+ needed_size, &needed_size);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_auth_pack_sc_blob failed.\n");
+ talloc_free(tok->data);
+ return ret;
+ }
+
+ tok->length = needed_size;
+ tok->type = type;
+
+ return EOK;
+}
+
+errno_t sss_authtok_set_sc_from_blob(struct sss_auth_token *tok,
+ const uint8_t *data,
+ size_t len)
+{
+ int ret;
+ char *pin = NULL;
+ size_t pin_len;
+ char *token_name = NULL;
+ size_t token_name_len;
+ char *module_name = NULL;
+ size_t module_name_len;
+ char *key_id = NULL;
+ size_t key_id_len;
+ TALLOC_CTX *tmp_ctx;
+
+ if (tok == NULL) {
+ return EFAULT;
+ }
+ if (data == NULL || len == 0) {
+ return EINVAL;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sss_auth_unpack_sc_blob(tmp_ctx, data, len, &pin, &pin_len,
+ &token_name, &token_name_len,
+ &module_name, &module_name_len,
+ &key_id, &key_id_len);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_auth_unpack_sc_blob failed.\n");
+ goto done;
+ }
+
+ ret = sss_authtok_set_sc(tok, SSS_AUTHTOK_TYPE_SC_PIN, pin, pin_len,
+ token_name, token_name_len,
+ module_name, module_name_len,
+ key_id, key_id_len);
+
+done:
+ talloc_free(tmp_ctx);
+
+ return ret;
+}
+
errno_t sss_authtok_set_sc_pin(struct sss_auth_token *tok, const char *pin,
size_t len)
{
@@ -435,15 +532,17 @@ errno_t sss_authtok_set_sc_pin(struct sss_auth_token *tok, const char *pin,
return EINVAL;
}
- sss_authtok_set_empty(tok);
-
- return sss_authtok_set_string(tok, SSS_AUTHTOK_TYPE_SC_PIN,
- "sc_pin", pin, len);
+ return sss_authtok_set_sc(tok, SSS_AUTHTOK_TYPE_SC_PIN, pin, len,
+ NULL, 0, NULL, 0, NULL, 0);
}
-errno_t sss_authtok_get_sc_pin(struct sss_auth_token *tok, const char **pin,
+errno_t sss_authtok_get_sc_pin(struct sss_auth_token *tok, const char **_pin,
size_t *len)
{
+ int ret;
+ const char *pin = NULL;
+ size_t pin_len;
+
if (!tok) {
return EFAULT;
}
@@ -451,9 +550,16 @@ errno_t sss_authtok_get_sc_pin(struct sss_auth_token *tok, const char **pin,
case SSS_AUTHTOK_TYPE_EMPTY:
return ENOENT;
case SSS_AUTHTOK_TYPE_SC_PIN:
- *pin = (const char *)tok->data;
+ ret = sss_authtok_get_sc(tok, &pin, &pin_len,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_get_sc failed.\n");
+ return ret;
+ }
+
+ *_pin = pin;
if (len) {
- *len = tok->length - 1;
+ *len = pin_len;
}
return EOK;
case SSS_AUTHTOK_TYPE_PASSWORD:
@@ -468,10 +574,202 @@ errno_t sss_authtok_get_sc_pin(struct sss_auth_token *tok, const char **pin,
void sss_authtok_set_sc_keypad(struct sss_auth_token *tok)
{
- if (!tok) {
+ if (tok == NULL) {
return;
}
+
sss_authtok_set_empty(tok);
tok->type = SSS_AUTHTOK_TYPE_SC_KEYPAD;
}
+
+errno_t sss_auth_unpack_sc_blob(TALLOC_CTX *mem_ctx,
+ const uint8_t *blob, size_t blob_len,
+ char **pin, size_t *_pin_len,
+ char **token_name, size_t *_token_name_len,
+ char **module_name, size_t *_module_name_len,
+ char **key_id, size_t *_key_id_len)
+{
+ size_t c;
+ uint32_t pin_len;
+ uint32_t token_name_len;
+ uint32_t module_name_len;
+ uint32_t key_id_len;
+
+ c = 0;
+
+ if (blob == NULL || blob_len == 0) {
+ pin_len = 0;
+ token_name_len = 0;
+ module_name_len = 0;
+ key_id_len = 0;
+ } else if (blob_len > 0
+ && strnlen((const char *) blob, blob_len) == blob_len - 1) {
+ pin_len = blob_len;
+ token_name_len = 0;
+ module_name_len = 0;
+ key_id_len = 0;
+ } else {
+ if (blob_len < 4 * sizeof(uint32_t)) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Blob too small.\n");
+ return EINVAL;
+ }
+
+ SAFEALIGN_COPY_UINT32(&pin_len, blob, &c);
+ SAFEALIGN_COPY_UINT32(&token_name_len, blob + c, &c);
+ SAFEALIGN_COPY_UINT32(&module_name_len, blob + c, &c);
+ SAFEALIGN_COPY_UINT32(&key_id_len, blob + c, &c);
+
+ if (blob_len != 4 * sizeof(uint32_t) + pin_len + token_name_len
+ + module_name_len + key_id_len) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Blob size mismatch.\n");
+ return EINVAL;
+ }
+ }
+
+ if (pin_len != 0) {
+ *pin = talloc_strndup(mem_ctx, (const char *) blob + c, pin_len);
+ if (*pin == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n");
+ return ENOMEM;
+ }
+ } else {
+ *pin = NULL;
+ }
+
+ if (token_name_len != 0) {
+ *token_name = talloc_strndup(mem_ctx, (const char *) blob + c + pin_len,
+ token_name_len);
+ if (*token_name == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n");
+ talloc_free(*pin);
+ return ENOMEM;
+ }
+ } else {
+ *token_name = NULL;
+ }
+
+ if (module_name_len != 0) {
+ *module_name = talloc_strndup(mem_ctx,
+ (const char *) blob + c + pin_len
+ + token_name_len,
+ module_name_len);
+ if (*module_name == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n");
+ talloc_free(*pin);
+ talloc_free(*token_name);
+ return ENOMEM;
+ }
+ } else {
+ *module_name = NULL;
+ }
+
+ if (key_id_len != 0) {
+ *key_id = talloc_strndup(mem_ctx,
+ (const char *) blob + c + pin_len
+ + token_name_len
+ + module_name_len,
+ key_id_len);
+ if (*key_id == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n");
+ talloc_free(*pin);
+ talloc_free(*token_name);
+ talloc_free(*module_name);
+ return ENOMEM;
+ }
+ } else {
+ *key_id = NULL;
+ }
+
+ /* Re-calculate length for the case where \0 was missing in the blob */
+ if (_pin_len != NULL) {
+ *_pin_len = (*pin == NULL) ? 0 : strlen(*pin);
+ }
+ if (_token_name_len != NULL) {
+ *_token_name_len = (*token_name == NULL) ? 0 : strlen(*token_name);
+ }
+ if (_module_name_len != NULL) {
+ *_module_name_len = (*module_name == NULL) ? 0 : strlen(*module_name);
+ }
+
+ if (_key_id_len != NULL) {
+ *_key_id_len = (*key_id == NULL) ? 0 : strlen(*key_id);
+ }
+
+ return EOK;
+}
+
+errno_t sss_authtok_get_sc(struct sss_auth_token *tok,
+ const char **_pin, size_t *_pin_len,
+ const char **_token_name, size_t *_token_name_len,
+ const char **_module_name, size_t *_module_name_len,
+ const char **_key_id, size_t *_key_id_len)
+{
+ size_t c = 0;
+ size_t pin_len;
+ size_t token_name_len;
+ size_t module_name_len;
+ size_t key_id_len;
+ uint32_t tmp_uint32_t;
+
+ if (!tok) {
+ return EFAULT;
+ }
+
+ if (tok->type != SSS_AUTHTOK_TYPE_SC_PIN
+ && tok->type != SSS_AUTHTOK_TYPE_SC_KEYPAD) {
+ return (tok->type == SSS_AUTHTOK_TYPE_EMPTY) ? ENOENT : EACCES;
+ }
+
+ if (tok->length < 4 * sizeof(uint32_t)) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Blob too small.\n");
+ return EINVAL;
+ }
+
+ SAFEALIGN_COPY_UINT32(&tmp_uint32_t, tok->data, &c);
+ pin_len = tmp_uint32_t - 1;
+ SAFEALIGN_COPY_UINT32(&tmp_uint32_t, tok->data + c, &c);
+ token_name_len = tmp_uint32_t - 1;
+ SAFEALIGN_COPY_UINT32(&tmp_uint32_t, tok->data + c, &c);
+ module_name_len = tmp_uint32_t -1;
+ SAFEALIGN_COPY_UINT32(&tmp_uint32_t, tok->data + c, &c);
+ key_id_len = tmp_uint32_t -1;
+
+ if (tok->length != 4 * sizeof(uint32_t) + 4 + pin_len + token_name_len
+ + module_name_len + key_id_len) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Blob size mismatch.\n");
+ return EINVAL;
+ }
+
+ if (_pin != NULL) {
+ *_pin = (const char *) tok->data + c;
+ }
+ if (_pin_len != NULL) {
+ *_pin_len = pin_len;
+ }
+
+ if (_token_name != NULL) {
+ *_token_name = (const char *) tok->data + c + pin_len + 1;
+ }
+ if (_token_name_len != NULL) {
+ *_token_name_len = token_name_len;
+ }
+
+ if (_module_name != NULL) {
+ *_module_name = (const char *) tok->data + c + pin_len + 1
+ + token_name_len + 1;
+ }
+ if (_module_name_len != NULL) {
+ *_module_name_len = module_name_len;
+ }
+
+ if (_key_id != NULL) {
+ *_key_id = (const char *) tok->data + c + pin_len + 1
+ + token_name_len + 1 + module_name_len + 1;
+ }
+ if (_key_id_len != NULL) {
+ *_key_id_len = key_id_len;
+ }
+
+ return EOK;
+}
diff --git a/src/util/authtok.h b/src/util/authtok.h
index f1a01a423..c146ba206 100644
--- a/src/util/authtok.h
+++ b/src/util/authtok.h
@@ -264,4 +264,88 @@ errno_t sss_authtok_get_sc_pin(struct sss_auth_token *tok, const char **pin,
*/
void sss_authtok_set_sc_keypad(struct sss_auth_token *tok);
+/**
+ * @brief Set complete Smart Card authentication blob including PKCS#11 token
+ * name, module name and key id.
+ *
+ * @param tok A pointer to an sss_auth_token
+ * @param type Authentication token type, may be
+ * SSS_AUTHTOK_TYPE_SC_PIN or SSS_AUTHTOK_TYPE_SC_KEYPAD
+ * @param pin A pointer to a const char *, that will point to a null
+ * terminated string containing the pin
+ * @param pin_len The length of the pin string, if set to 0 it will be
+ * calculated
+ * @param token_name A pointer to a const char *, that will point to a null
+ * terminated string containing the PKCS#11 token name
+ * @param token_name_len The length of the token name string, if set to 0 it
+ * will be calculated
+ * @param module_name A pointer to a const char *, that will point to a null
+ * terminated string containing the PKCS#11 module name
+ * @param module_name_len The length of the module name string, if set to 0 it
+ * will be calculated
+ * @param key_id A pointer to a const char *, that will point to a null
+ * terminated string containing the PKCS#11 key id
+ * @param key_id_len The length of the key id string, if set to 0 it will be
+ * calculated
+ *
+ * @return EOK on success
+ * EINVAL unexpected or inval input
+ * ENOMEM memory allocation error
+ */
+errno_t sss_authtok_set_sc(struct sss_auth_token *tok,
+ enum sss_authtok_type type,
+ const char *pin, size_t pin_len,
+ const char *token_name, size_t token_name_len,
+ const char *module_name, size_t module_name_len,
+ const char *key_id, size_t key_id_len);
+/**
+ * @brief Set a Smart Card authentication data, replacing any previous data
+ *
+ * @param tok A pointer to a sss_auth_token structure to change, also
+ * used as a memory context to allocate the internal data.
+ * @param data Smart Card authentication data blob
+ * @param len The length of the blob
+ *
+ * @return EOK on success
+ * ENOMEM on error
+ */
+errno_t sss_authtok_set_sc_from_blob(struct sss_auth_token *tok,
+ const uint8_t *data,
+ size_t len);
+
+/**
+ * @brief Get complete Smart Card authtoken data
+ *
+ * @param tok A pointer to a sss_auth_token structure
+ * @param[out] _pin A pointer to a const char *, that will point to
+ * a null terminated string holding the pin,
+ * may not be modified or freed
+ * @param[out] _pin__len Length of the pin
+ * @param[out] _token_name A pointer to a const char *, that will point to
+ * a null terminated string holding the PKCS#11
+ * token name, may not be modified or freed
+ * @param[out] _token_name_len Length of the PKCS#11 token name
+ * @param[out] _module_name A pointer to a const char *, that will point to
+ * a null terminated string holding the PKCS#11
+ * module name, may not be modified or freed
+ * @param[out] _module_name_len Length of the PKCS#11 module name
+ * @param[out] _key_id A pointer to a const char *, that will point to
+ * a null terminated string holding the PKCS#11
+ * key id, may not be modified or freed
+ * @param[out] _key_id_len Length of the PKCS#11 key id
+ *
+ * Any of the output pointers may be NULL if the caller does not need the
+ * specific item.
+ *
+ * @return EOK on success
+ * EFAULT missing token
+ * EINVAL if input data is not consistent
+ * ENOENT if the token is empty
+ * EACCESS if the token is not a Smart Card token
+ */
+errno_t sss_authtok_get_sc(struct sss_auth_token *tok,
+ const char **_pin, size_t *_pin_len,
+ const char **_token_name, size_t *_token_name_len,
+ const char **_module_name, size_t *_module_name_len,
+ const char **_key_id, size_t *_key_id_len);
#endif /* __AUTHTOK_H__ */