45726939a48e605b0166521f94300ae04981a3a7Sumit Bose/*
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose SSSD
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose Helper child to commmunicate with SmartCard via NSS
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose Authors:
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose Sumit Bose <sbose@redhat.com>
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose Copyright (C) 2015 Red Hat
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose This program is free software; you can redistribute it and/or modify
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose it under the terms of the GNU General Public License as published by
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose the Free Software Foundation; either version 3 of the License, or
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose (at your option) any later version.
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose This program is distributed in the hope that it will be useful,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose but WITHOUT ANY WARRANTY; without even the implied warranty of
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose GNU General Public License for more details.
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose You should have received a copy of the GNU General Public License
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose along with this program. If not, see <http://www.gnu.org/licenses/>.
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose*/
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose#include <unistd.h>
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose#include <stdio.h>
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose#include <stdlib.h>
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose#include <string.h>
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose#include <popt.h>
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose#include "util/util.h"
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose#include <nss.h>
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose#include <base64.h>
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose#include <cryptohi.h>
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose#include <secmod.h>
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose#include <cert.h>
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose#include <keyhi.h>
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose#include <pk11pub.h>
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose#include <prerror.h>
544a20de7667f05c1a406c4dea0706b0ab507430Sumit Bose#include <ocsp.h>
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose#include "util/child_common.h"
cc2d77d5218c188119fa954c856e858cbde76947Pavel Březina#include "providers/backend.h"
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose#include "util/crypto/sss_crypto.h"
544a20de7667f05c1a406c4dea0706b0ab507430Sumit Bose#include "util/cert.h"
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
787ba9c882f1d7ff9ea4f2745e779c5fb04dfafcSumit Bose#define EXP_USAGES ( certificateUsageSSLClient \
787ba9c882f1d7ff9ea4f2745e779c5fb04dfafcSumit Bose | certificateUsageSSLServer \
787ba9c882f1d7ff9ea4f2745e779c5fb04dfafcSumit Bose | certificateUsageSSLServerWithStepUp \
787ba9c882f1d7ff9ea4f2745e779c5fb04dfafcSumit Bose | certificateUsageEmailSigner \
787ba9c882f1d7ff9ea4f2745e779c5fb04dfafcSumit Bose | certificateUsageEmailRecipient \
787ba9c882f1d7ff9ea4f2745e779c5fb04dfafcSumit Bose | certificateUsageObjectSigner \
787ba9c882f1d7ff9ea4f2745e779c5fb04dfafcSumit Bose | certificateUsageStatusResponder \
787ba9c882f1d7ff9ea4f2745e779c5fb04dfafcSumit Bose | certificateUsageSSLCA )
787ba9c882f1d7ff9ea4f2745e779c5fb04dfafcSumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Boseenum op_mode {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose OP_NONE,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose OP_AUTH,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose OP_PREAUTH
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose};
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Boseenum pin_mode {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose PIN_NONE,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose PIN_STDIN,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose PIN_KEYPAD
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose};
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bosestatic char *password_passthrough(PK11SlotInfo *slot, PRBool retry, void *arg)
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose{
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose /* give up if 1) no password was supplied, or 2) the password has already
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose * been rejected once by this token. */
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (retry || (arg == NULL)) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose return NULL;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose return PL_strdup((char *)arg);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose}
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bosestatic char *get_key_id_str(PK11SlotInfo *slot, CERTCertificate *cert)
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose{
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose SECItem *key_id = NULL;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose char *key_id_str = NULL;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose key_id = PK11_GetLowLevelKeyIDForCert(slot, cert, NULL);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose if (key_id == NULL) {
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose DEBUG(SSSDBG_OP_FAILURE,
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose "PK11_GetLowLevelKeyIDForCert failed [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose return NULL;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose key_id_str = CERT_Hexify(key_id, PR_FALSE);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose SECITEM_FreeItem(key_id, PR_TRUE);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose if (key_id_str == NULL) {
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose DEBUG(SSSDBG_OP_FAILURE, "CERT_Hexify failed [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose return NULL;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose return key_id_str;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose}
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Boseint do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
aa35995ef056aa8ae052a47c62c6750b7adf065eSumit Bose enum op_mode mode, const char *pin,
aa35995ef056aa8ae052a47c62c6750b7adf065eSumit Bose struct cert_verify_opts *cert_verify_opts,
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose const char *module_name_in, const char *token_name_in,
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose const char *key_id_in, char **_multi)
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose{
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose int ret;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose SECStatus rv;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose NSSInitContext *nss_ctx;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose SECMODModuleList *mod_list;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose SECMODModuleList *mod_list_item;
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose SECMODModule *module;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose const char *slot_name;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose const char *token_name;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose uint32_t flags = NSS_INIT_READONLY
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose | NSS_INIT_FORCEOPEN
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose | NSS_INIT_NOROOTINIT
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose | NSS_INIT_OPTIMIZESPACE
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose | NSS_INIT_PK11RELOAD;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose NSSInitParameters parameters = { 0 };
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose parameters.length = sizeof (parameters);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose PK11SlotInfo *slot = NULL;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose CK_SLOT_ID slot_id;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose SECMODModuleID module_id;
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose const char *module_name;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose CERTCertList *cert_list = NULL;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose CERTCertListNode *cert_list_node;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose const PK11DefaultArrayEntry friendly_attr = { "Publicly-readable certs",
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose SECMOD_FRIENDLY_FLAG,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose CKM_INVALID_MECHANISM };
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose CERTCertDBHandle *handle;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose unsigned char random_value[128];
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose SECKEYPrivateKey *priv_key;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose SECOidTag algtag;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose SECItem signed_random_value = {0};
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose SECKEYPublicKey *pub_key;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose CERTCertificate *found_cert = NULL;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose PK11SlotList *list = NULL;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose PK11SlotListElement *le;
57cefea8305a57c1c0491afb739813b7f17d5a25Sumit Bose const char *label;
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose char *key_id_str = NULL;
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose CERTCertList *valid_certs = NULL;
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose char *cert_b64 = NULL;
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose char *multi = NULL;
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose PRCList *node;
787ba9c882f1d7ff9ea4f2745e779c5fb04dfafcSumit Bose SECCertificateUsage returned_usage = 0;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose nss_ctx = NSS_InitContext(nss_db, "", "", SECMOD_DB, &parameters, flags);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (nss_ctx == NULL) {
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose DEBUG(SSSDBG_OP_FAILURE, "NSS_InitContext failed [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose return EIO;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose PK11_SetPasswordFunc(password_passthrough);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "Default Module List:\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose mod_list = SECMOD_GetDefaultModuleList();
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose for (mod_list_item = mod_list; mod_list_item != NULL;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose mod_list_item = mod_list_item->next) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "common name: [%s].\n",
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose mod_list_item->module->commonName);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "dll name: [%s].\n",
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose mod_list_item->module->dllName);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "Dead Module List:\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose mod_list = SECMOD_GetDeadModuleList();
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose for (mod_list_item = mod_list; mod_list_item != NULL;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose mod_list_item = mod_list_item->next) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "common name: [%s].\n",
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose mod_list_item->module->commonName);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "dll name: [%s].\n",
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose mod_list_item->module->dllName);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "DB Module List:\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose mod_list = SECMOD_GetDBModuleList();
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose for (mod_list_item = mod_list; mod_list_item != NULL;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose mod_list_item = mod_list_item->next) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "common name: [%s].\n",
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose mod_list_item->module->commonName);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "dll name: [%s].\n",
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose mod_list_item->module->dllName);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE,
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose NULL);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose if (list == NULL) {
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose DEBUG(SSSDBG_OP_FAILURE, "PK11_GetAllTokens failed.\n");
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose return EIO;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose for (le = list->head; le; le = le->next) {
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose CK_SLOT_INFO slInfo;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose slInfo.flags = 0;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose rv = PK11_GetSlotInfo(le->slot, &slInfo);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose DEBUG(SSSDBG_TRACE_ALL,
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose "Description [%s] Manufacturer [%s] flags [%lu].\n",
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose slInfo.slotDescription, slInfo.manufacturerID, slInfo.flags);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose if (rv == SECSuccess && (slInfo.flags & CKF_REMOVABLE_DEVICE)) {
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose slot = PK11_ReferenceSlot(le->slot);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose break;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose PK11_FreeSlotList(list);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose if (slot == NULL) {
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose DEBUG(SSSDBG_OP_FAILURE, "No removable slots found.\n");
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose return EIO;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose slot_id = PK11_GetSlotID(slot);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose module_id = PK11_GetModuleID(slot);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose slot_name = PK11_GetSlotName(slot);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose token_name = PK11_GetTokenName(slot);
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose module = PK11_GetModule(slot);
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose module_name = module->dllName == NULL ? "NSS-Internal" : module->dllName;
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "Found [%s] in slot [%s][%d] of module [%d][%s].\n",
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose token_name, slot_name, (int) slot_id, (int) module_id, module_name);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (PK11_IsFriendly(slot)) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "Token is friendly.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose } else {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose "Token is NOT friendly.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (mode == OP_PREAUTH) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "Trying to switch to friendly to read certificate.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose rv = PK11_UpdateSlotAttribute(slot, &friendly_attr, PR_TRUE);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (rv != SECSuccess) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_OP_FAILURE,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose "PK11_UpdateSlotAttribute failed, continue.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose /* TODO: check PK11_ProtectedAuthenticationPath() and return the result */
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (mode == OP_AUTH || PK11_NeedLogin(slot)) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "Login required.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (pin != NULL) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose rv = PK11_Authenticate(slot, PR_FALSE, discard_const(pin));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (rv != SECSuccess) {
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose DEBUG(SSSDBG_OP_FAILURE, "PK11_Authenticate failed: [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose return EIO;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose } else {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE,
346d6d8bf5fdb446921d754c07c8a7d913a048d5René Genz "Login required but no PIN available, continue.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose } else {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "Login NOT required.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose cert_list = PK11_ListCertsInSlot(slot);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (cert_list == NULL) {
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose DEBUG(SSSDBG_OP_FAILURE, "PK11_ListCertsInSlot failed: [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose return EIO;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose for (cert_list_node = CERT_LIST_HEAD(cert_list);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose !CERT_LIST_END(cert_list_node, cert_list);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose cert_list_node = CERT_LIST_NEXT(cert_list_node)) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (cert_list_node->cert) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "found cert[%s][%s]\n",
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose cert_list_node->cert->nickname,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose cert_list_node->cert->subjectName);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose } else {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "--- empty cert list node ---\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose handle = CERT_GetDefaultCertDB();
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (handle == NULL) {
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose DEBUG(SSSDBG_OP_FAILURE, "CERT_GetDefaultCertDB failed: [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose return EIO;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
aa35995ef056aa8ae052a47c62c6750b7adf065eSumit Bose if (cert_verify_opts->do_ocsp) {
544a20de7667f05c1a406c4dea0706b0ab507430Sumit Bose rv = CERT_EnableOCSPChecking(handle);
544a20de7667f05c1a406c4dea0706b0ab507430Sumit Bose if (rv != SECSuccess) {
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose DEBUG(SSSDBG_OP_FAILURE,
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose "CERT_EnableOCSPChecking failed: [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
544a20de7667f05c1a406c4dea0706b0ab507430Sumit Bose return EIO;
544a20de7667f05c1a406c4dea0706b0ab507430Sumit Bose }
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose if (cert_verify_opts->ocsp_default_responder != NULL
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose && cert_verify_opts->ocsp_default_responder_signing_cert != NULL) {
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose rv = CERT_SetOCSPDefaultResponder(handle,
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose cert_verify_opts->ocsp_default_responder,
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose cert_verify_opts->ocsp_default_responder_signing_cert);
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose if (rv != SECSuccess) {
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose DEBUG(SSSDBG_OP_FAILURE,
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose "CERT_SetOCSPDefaultResponder failed: [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose return EIO;
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose }
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose rv = CERT_EnableOCSPDefaultResponder(handle);
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose if (rv != SECSuccess) {
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose DEBUG(SSSDBG_OP_FAILURE,
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose "CERT_EnableOCSPDefaultResponder failed: [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose return EIO;
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose }
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose }
544a20de7667f05c1a406c4dea0706b0ab507430Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose found_cert = NULL;
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose valid_certs = CERT_NewCertList();
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose if (valid_certs == NULL) {
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose DEBUG(SSSDBG_OP_FAILURE, "CERT_NewCertList failed [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose ret = ENOMEM;
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose goto done;
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose }
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "Filtered certificates:\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose for (cert_list_node = CERT_LIST_HEAD(cert_list);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose !CERT_LIST_END(cert_list_node, cert_list);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose cert_list_node = CERT_LIST_NEXT(cert_list_node)) {
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose if (cert_list_node->cert == NULL) {
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose DEBUG(SSSDBG_TRACE_ALL, "--- empty cert list node ---\n");
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose continue;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose DEBUG(SSSDBG_TRACE_ALL,
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose "found cert[%s][%s]\n",
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose cert_list_node->cert->nickname,
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose cert_list_node->cert->subjectName);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose if (cert_verify_opts->do_verification) {
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose rv = CERT_VerifyCertificateNow(handle, cert_list_node->cert,
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose PR_TRUE,
177ab84f0e336b75289a3ac0b2df25bd5ab5198bSumit Bose certificateUsageCheckAllUsages,
787ba9c882f1d7ff9ea4f2745e779c5fb04dfafcSumit Bose NULL, &returned_usage);
787ba9c882f1d7ff9ea4f2745e779c5fb04dfafcSumit Bose if (rv != SECSuccess || ((returned_usage & EXP_USAGES) == 0)) {
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose DEBUG(SSSDBG_OP_FAILURE,
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose "Certificate [%s][%s] not valid [%d][%s], skipping.\n",
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose cert_list_node->cert->nickname,
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose cert_list_node->cert->subjectName,
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose continue;
d0de7701d44c7a75210a9cb04634913ce3a94bfbSumit Bose }
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose }
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose if (key_id_in != NULL) {
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose PORT_Free(key_id_str);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose key_id_str = NULL;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose key_id_str = get_key_id_str(slot, cert_list_node->cert);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose }
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose /* Check if we found the certificates we needed for authentication or
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose * the requested ones for pre-auth. For authentication all attributes
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose * must be given and match, for pre-auth only the given ones must
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose * match. */
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose DEBUG(SSSDBG_TRACE_ALL, "%s %s %s %s %s %s.\n",
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose module_name_in, module_name, token_name_in, token_name,
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose key_id_in, key_id_str);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose if ((mode == OP_AUTH
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose && module_name_in != NULL
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose && token_name_in != NULL
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose && key_id_in != NULL
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose && key_id_str != NULL
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose && strcmp(key_id_in, key_id_str) == 0
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose && strcmp(token_name_in, token_name) == 0
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose && strcmp(module_name_in, module_name) == 0)
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose || (mode == OP_PREAUTH
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose && (module_name_in == NULL
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose || (module_name_in != NULL
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose && strcmp(module_name_in, module_name) == 0))
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose && (token_name_in == NULL
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose || (token_name_in != NULL
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose && strcmp(token_name_in, token_name) == 0))
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose && (key_id_in == NULL
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose || (key_id_in != NULL && key_id_str != NULL
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose && strcmp(key_id_in, key_id_str) == 0)))) {
d0de7701d44c7a75210a9cb04634913ce3a94bfbSumit Bose
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose rv = CERT_AddCertToListTail(valid_certs, cert_list_node->cert);
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose if (rv != SECSuccess) {
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose DEBUG(SSSDBG_OP_FAILURE,
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose "CERT_AddCertToListTail failed [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose ret = EIO;
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose goto done;
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose /* Disable OCSP default responder so that NSS can shutdown properly */
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose if (cert_verify_opts->do_ocsp
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose && cert_verify_opts->ocsp_default_responder != NULL
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose && cert_verify_opts->ocsp_default_responder_signing_cert != NULL) {
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose rv = CERT_DisableOCSPDefaultResponder(handle);
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose if (rv != SECSuccess) {
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose DEBUG(SSSDBG_OP_FAILURE,
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose "CERT_DisableOCSPDefaultResponder failed: [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose }
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose }
53ef8f81b60929a6c866efdd133627e7d7d61705Sumit Bose
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose if (CERT_LIST_EMPTY(valid_certs)) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "No certificate found.\n");
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose *_multi = NULL;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ret = EOK;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose goto done;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (mode == OP_AUTH) {
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose cert_list_node = CERT_LIST_HEAD(valid_certs);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose if (!CERT_LIST_END(CERT_LIST_NEXT(cert_list_node), valid_certs)) {
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose DEBUG(SSSDBG_FATAL_FAILURE,
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose "More than one certificate found for authentication, "
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose "aborting!\n");
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose ret = EINVAL;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose goto done;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose }
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose found_cert = cert_list_node->cert;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose if (found_cert == NULL) {
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose DEBUG(SSSDBG_FATAL_FAILURE,
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose "No certificate found for authentication, aborting!\n");
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose ret = EINVAL;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose goto done;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose }
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose rv = PK11_GenerateRandom(random_value, sizeof(random_value));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (rv != SECSuccess) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_OP_FAILURE,
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose "PK11_GenerateRandom failed [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose return EIO;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose priv_key = PK11_FindPrivateKeyFromCert(slot, found_cert, NULL);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (priv_key == NULL) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_OP_FAILURE,
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose "PK11_FindPrivateKeyFromCert failed [%d][%s]."
346d6d8bf5fdb446921d754c07c8a7d913a048d5René Genz "Maybe PIN is missing.\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ret = EIO;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose goto done;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose algtag = SEC_GetSignatureAlgorithmOidTag(priv_key->keyType,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose SEC_OID_SHA1);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (algtag == SEC_OID_UNKNOWN) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose SECKEY_DestroyPrivateKey(priv_key);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_OP_FAILURE,
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose "SEC_GetSignatureAlgorithmOidTag failed [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ret = EIO;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose goto done;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose rv = SEC_SignData(&signed_random_value,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose random_value, sizeof(random_value),
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose priv_key, algtag);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose SECKEY_DestroyPrivateKey(priv_key);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (rv != SECSuccess) {
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose DEBUG(SSSDBG_OP_FAILURE, "SEC_SignData failed [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ret = EIO;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose goto done;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose pub_key = CERT_ExtractPublicKey(found_cert);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (pub_key == NULL) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_OP_FAILURE,
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose "CERT_ExtractPublicKey failed [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ret = EIO;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose goto done;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose rv = VFY_VerifyData(random_value, sizeof(random_value),
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose pub_key, &signed_random_value, algtag,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose NULL);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose SECKEY_DestroyPublicKey(pub_key);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (rv != SECSuccess) {
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose DEBUG(SSSDBG_OP_FAILURE, "VFY_VerifyData failed [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ret = EACCES;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose goto done;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_ALL,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose "Certificate verified and validated.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose multi = talloc_strdup(mem_ctx, "");
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose if (multi == NULL) {
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create output string.\n");
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose ret = ENOMEM;
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose goto done;
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose }
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose for (cert_list_node = CERT_LIST_HEAD(valid_certs);
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose !CERT_LIST_END(cert_list_node, valid_certs);
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose cert_list_node = CERT_LIST_NEXT(cert_list_node)) {
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose found_cert = cert_list_node->cert;
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose PORT_Free(key_id_str);
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose key_id_str = get_key_id_str(slot, found_cert);
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose if (key_id_str == NULL) {
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose DEBUG(SSSDBG_OP_FAILURE, "get_key_id_str [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose ret = ENOMEM;
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose goto done;
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
57cefea8305a57c1c0491afb739813b7f17d5a25Sumit Bose /* The NSS nickname is typically token_name:label, so the label starts
57cefea8305a57c1c0491afb739813b7f17d5a25Sumit Bose * after the ':'. */
57cefea8305a57c1c0491afb739813b7f17d5a25Sumit Bose if (found_cert->nickname != NULL) {
57cefea8305a57c1c0491afb739813b7f17d5a25Sumit Bose if ((label = strchr(found_cert->nickname, ':')) == NULL) {
57cefea8305a57c1c0491afb739813b7f17d5a25Sumit Bose label = found_cert->nickname;
57cefea8305a57c1c0491afb739813b7f17d5a25Sumit Bose } else {
57cefea8305a57c1c0491afb739813b7f17d5a25Sumit Bose label++;
57cefea8305a57c1c0491afb739813b7f17d5a25Sumit Bose }
57cefea8305a57c1c0491afb739813b7f17d5a25Sumit Bose } else {
57cefea8305a57c1c0491afb739813b7f17d5a25Sumit Bose label = "- no label found -";
57cefea8305a57c1c0491afb739813b7f17d5a25Sumit Bose }
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose talloc_free(cert_b64);
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose cert_b64 = sss_base64_encode(mem_ctx, found_cert->derCert.data,
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose found_cert->derCert.len);
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose if (cert_b64 == NULL) {
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "sss_base64_encode failed.\n");
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose ret = ENOMEM;
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose goto done;
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose }
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose DEBUG(SSSDBG_TRACE_ALL, "Found certificate has key id [%s].\n",
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose key_id_str);
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose
57cefea8305a57c1c0491afb739813b7f17d5a25Sumit Bose multi = talloc_asprintf_append(multi, "%s\n%s\n%s\n%s\n%s\n",
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose token_name, module_name, key_id_str,
57cefea8305a57c1c0491afb739813b7f17d5a25Sumit Bose label, cert_b64);
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose }
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose *_multi = multi;
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ret = EOK;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bosedone:
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (slot != NULL) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose PK11_FreeSlot(slot);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose if (valid_certs != NULL) {
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose /* The certificates can be found in valid_certs and cert_list and
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose * CERT_DestroyCertList() will free the certificates as well. To avoid
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose * a double free the nodes from valid_certs are removed first because
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose * valid_certs will only have a sub-set of the certificates. */
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose while (!PR_CLIST_IS_EMPTY(&valid_certs->list)) {
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose node = PR_LIST_HEAD(&valid_certs->list);
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose PR_REMOVE_LINK(node);
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose }
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose CERT_DestroyCertList(valid_certs);
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose }
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (cert_list != NULL) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose CERT_DestroyCertList(cert_list);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose PORT_Free(key_id_str);
ead25e32c52c8c2f5fd9abd179e9e81de58f9ca3Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose PORT_Free(signed_random_value.data);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose talloc_free(cert_b64);
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose rv = NSS_ShutdownContext(nss_ctx);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (rv != SECSuccess) {
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose DEBUG(SSSDBG_OP_FAILURE, "NSS_ShutdownContext failed [%d][%s].\n",
08d1f8c0d6eece6a48201d7f8824b282eac3458dSumit Bose PR_GetError(), PORT_ErrorToString(PR_GetError()));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose return ret;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose}
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bosestatic errno_t p11c_recv_data(TALLOC_CTX *mem_ctx, int fd, char **pin)
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose{
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose uint8_t buf[IN_BUF_SIZE];
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ssize_t len;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose errno_t ret;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose char *str;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose errno = 0;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose len = sss_atomic_read_s(fd, buf, IN_BUF_SIZE);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (len == -1) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ret = errno;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ret = (ret == 0) ? EINVAL: ret;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose "read failed [%d][%s].\n", ret, strerror(ret));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose return ret;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (len == 0 || *buf == '\0') {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "Missing PIN.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose return EINVAL;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose str = talloc_strndup(mem_ctx, (char *) buf, len);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (str == NULL) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose return ENOMEM;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (strlen(str) != len) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose "Input contains additional data, only PIN expected.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose talloc_free(str);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose return EINVAL;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose *pin = str;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose return EOK;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose}
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Boseint main(int argc, const char *argv[])
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose{
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose int opt;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose poptContext pc;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose int debug_fd = -1;
a24954cc19285b197fb287bfa7aa01949c92b17dLukas Slebodnik const char *opt_logger = NULL;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose errno_t ret;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose TALLOC_CTX *main_ctx = NULL;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose enum op_mode mode = OP_NONE;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose enum pin_mode pin_mode = PIN_NONE;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose char *pin = NULL;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose char *nss_db = NULL;
aa35995ef056aa8ae052a47c62c6750b7adf065eSumit Bose struct cert_verify_opts *cert_verify_opts;
544a20de7667f05c1a406c4dea0706b0ab507430Sumit Bose char *verify_opts = NULL;
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose char *multi = NULL;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose char *module_name = NULL;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose char *token_name = NULL;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose char *key_id = NULL;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose struct poptOption long_options[] = {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose POPT_AUTOHELP
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose _("Debug level"), NULL},
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose {"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose _("Add debug timestamps"), NULL},
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose {"debug-microseconds", 0, POPT_ARG_INT, &debug_microseconds, 0,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose _("Show timestamps with microseconds"), NULL},
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose {"debug-fd", 0, POPT_ARG_INT, &debug_fd, 0,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose _("An open file descriptor for the debug logs"), NULL},
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose &debug_to_stderr, 0,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose _("Send the debug output to stderr directly."), NULL },
cb75b275d15beedd1fdecc1f8ced657fba282218Lukas Slebodnik SSSD_LOGGER_OPTS
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose {"auth", 0, POPT_ARG_NONE, NULL, 'a', _("Run in auth mode"), NULL},
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose {"pre", 0, POPT_ARG_NONE, NULL, 'p', _("Run in pre-auth mode"), NULL},
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose {"pin", 0, POPT_ARG_NONE, NULL, 'i', _("Expect PIN on stdin"), NULL},
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose {"keypad", 0, POPT_ARG_NONE, NULL, 'k', _("Expect PIN on keypad"),
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose NULL},
544a20de7667f05c1a406c4dea0706b0ab507430Sumit Bose {"verify", 0, POPT_ARG_STRING, &verify_opts, 0 , _("Tune validation"),
544a20de7667f05c1a406c4dea0706b0ab507430Sumit Bose NULL},
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose {"nssdb", 0, POPT_ARG_STRING, &nss_db, 0, _("NSS DB to use"),
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose NULL},
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose {"module_name", 0, POPT_ARG_STRING, &module_name, 0,
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose _("Module name for authentication"), NULL},
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose {"token_name", 0, POPT_ARG_STRING, &token_name, 0,
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose _("Token name for authentication"), NULL},
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose {"key_id", 0, POPT_ARG_STRING, &key_id, 0,
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose _("Key ID for authentication"), NULL},
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose POPT_TABLEEND
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose };
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose /* Set debug level to invalid value so we can decide if -d 0 was used. */
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose debug_level = SSSDBG_INVALID;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
ae627e216689b0a5834f36aaaa007ed584ef033dPetr Cech /*
3be9e26dcd169d44ae105f1b8a0674464c700b77Sumit Bose * This child can run as root or as sssd user relying on policy kit to
3be9e26dcd169d44ae105f1b8a0674464c700b77Sumit Bose * grant access to pcscd. This means that no setuid or setgid bit must be
3be9e26dcd169d44ae105f1b8a0674464c700b77Sumit Bose * set on the binary. We still should make sure to run with a restrictive
3be9e26dcd169d44ae105f1b8a0674464c700b77Sumit Bose * umask but do not have to make additional precautions like clearing the
3be9e26dcd169d44ae105f1b8a0674464c700b77Sumit Bose * environment. This would allow to use e.g. pkcs11-spy.so for further
3be9e26dcd169d44ae105f1b8a0674464c700b77Sumit Bose * debugging.
ae627e216689b0a5834f36aaaa007ed584ef033dPetr Cech */
ae627e216689b0a5834f36aaaa007ed584ef033dPetr Cech umask(SSS_DFL_UMASK);
13f30f69eec02d0c0aaccc7b544dee1326a5e9d4Jakub Hrozek
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose pc = poptGetContext(argv[0], argc, argv, long_options, 0);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose while ((opt = poptGetNextOpt(pc)) != -1) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose switch(opt) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose case 'a':
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (mode != OP_NONE) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose fprintf(stderr,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose "\n--auth and --pre are mutually exclusive and " \
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose "should be only used once.\n\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose poptPrintUsage(pc, stderr, 0);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose _exit(-1);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose mode = OP_AUTH;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose break;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose case 'p':
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (mode != OP_NONE) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose fprintf(stderr,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose "\n--auth and --pre are mutually exclusive and " \
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose "should be only used once.\n\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose poptPrintUsage(pc, stderr, 0);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose _exit(-1);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose mode = OP_PREAUTH;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose break;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose case 'i':
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (pin_mode != PIN_NONE) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose fprintf(stderr, "\n--pin and --keypad are mutually exclusive " \
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose "and should be only used once.\n\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose poptPrintUsage(pc, stderr, 0);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose _exit(-1);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose pin_mode = PIN_STDIN;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose break;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose case 'k':
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (pin_mode != PIN_NONE) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose fprintf(stderr, "\n--pin and --keypad are mutually exclusive " \
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose "and should be only used once.\n\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose poptPrintUsage(pc, stderr, 0);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose _exit(-1);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose pin_mode = PIN_KEYPAD;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose break;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose default:
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose fprintf(stderr, "\nInvalid option %s: %s\n\n",
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose poptBadOption(pc, 0), poptStrerror(opt));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose poptPrintUsage(pc, stderr, 0);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose _exit(-1);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (nss_db == NULL) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose fprintf(stderr, "\nMissing NSS DB --nssdb must be specified.\n\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose poptPrintUsage(pc, stderr, 0);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose _exit(-1);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (mode == OP_NONE) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose fprintf(stderr, "\nMissing operation mode, " \
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose "either --auth or --pre must be specified.\n\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose poptPrintUsage(pc, stderr, 0);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose _exit(-1);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose } else if (mode == OP_AUTH && pin_mode == PIN_NONE) {
346d6d8bf5fdb446921d754c07c8a7d913a048d5René Genz fprintf(stderr, "\nMissing PIN mode for authentication, " \
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose "either --pin or --keypad must be specified.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose poptPrintUsage(pc, stderr, 0);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose _exit(-1);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose poptFreeContext(pc);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG_INIT(debug_level);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose debug_prg_name = talloc_asprintf(NULL, "[sssd[p11_child[%d]]]", getpid());
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (debug_prg_name == NULL) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose goto fail;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (debug_fd != -1) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ret = set_debug_file_from_fd(debug_fd);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (ret != EOK) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
a24954cc19285b197fb287bfa7aa01949c92b17dLukas Slebodnik opt_logger = sss_logger_str[FILES_LOGGER];
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
a24954cc19285b197fb287bfa7aa01949c92b17dLukas Slebodnik
cb75b275d15beedd1fdecc1f8ced657fba282218Lukas Slebodnik sss_set_logger(opt_logger);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_FUNC, "p11_child started.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_INTERNAL, "Running in [%s] mode.\n",
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose mode == OP_AUTH ? "auth"
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose : (mode == OP_PREAUTH ? "pre-auth" : "unknown"));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_INTERNAL,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose "Running with effective IDs: [%"SPRIuid"][%"SPRIgid"].\n",
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose geteuid(), getegid());
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_TRACE_INTERNAL,
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose "Running with real IDs [%"SPRIuid"][%"SPRIgid"].\n",
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose getuid(), getgid());
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose main_ctx = talloc_new(NULL);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (main_ctx == NULL) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose talloc_free(discard_const(debug_prg_name));
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose goto fail;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose talloc_steal(main_ctx, debug_prg_name);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose if (mode == OP_AUTH && (module_name == NULL || token_name == NULL
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose || key_id == NULL)) {
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose DEBUG(SSSDBG_FATAL_FAILURE,
346d6d8bf5fdb446921d754c07c8a7d913a048d5René Genz "--module_name, --token_name and --key_id must be given for "
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose "authentication");
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose ret = EINVAL;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose goto fail;
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose }
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose
aa35995ef056aa8ae052a47c62c6750b7adf065eSumit Bose ret = parse_cert_verify_opts(main_ctx, verify_opts, &cert_verify_opts);
aa35995ef056aa8ae052a47c62c6750b7adf065eSumit Bose if (ret != EOK) {
aa35995ef056aa8ae052a47c62c6750b7adf065eSumit Bose DEBUG(SSSDBG_FATAL_FAILURE, "Failed to parse verifiy option.\n");
aa35995ef056aa8ae052a47c62c6750b7adf065eSumit Bose goto fail;
544a20de7667f05c1a406c4dea0706b0ab507430Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (mode == OP_AUTH && pin_mode == PIN_STDIN) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose ret = p11c_recv_data(main_ctx, STDIN_FILENO, &pin);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (ret != EOK) {
346d6d8bf5fdb446921d754c07c8a7d913a048d5René Genz DEBUG(SSSDBG_FATAL_FAILURE, "Failed to read PIN.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose goto fail;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose ret = do_work(main_ctx, nss_db, mode, pin, cert_verify_opts, module_name,
0a8024af282b271ad2185f68703d9f4e766d2bdcSumit Bose token_name, key_id, &multi);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose if (ret != EOK) {
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "do_work failed.\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose goto fail;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose if (multi != NULL) {
39fd336e4390ece3a8465714735ef4203f329e54Sumit Bose fprintf(stdout, "%s", multi);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose }
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose talloc_free(main_ctx);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose return EXIT_SUCCESS;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bosefail:
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "p11_child failed!\n");
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose close(STDOUT_FILENO);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose talloc_free(main_ctx);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose return EXIT_FAILURE;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose}