static krb5_error_code
pkinit_identity_process_option(krb5_context context,
                               pkinit_plg_crypto_context plg_cryptoctx,
                               pkinit_req_crypto_context req_cryptoctx,
                               pkinit_identity_opts *idopts,
                               pkinit_identity_crypto_context id_cryptoctx,
                               int attr,
                               const char *value)
{
    krb5_error_code retval = 0;

    switch (attr) {
    case PKINIT_ID_OPT_USER_IDENTITY:
        retval = process_option_identity(context, plg_cryptoctx,
                                         req_cryptoctx, idopts,
                                         id_cryptoctx, value);
        break;
    case PKINIT_ID_OPT_ANCHOR_CAS:
        retval = process_option_ca_crl(context, plg_cryptoctx,
                                       req_cryptoctx, idopts,
                                       id_cryptoctx, value,
                                       CATYPE_ANCHORS);
        break;
    case PKINIT_ID_OPT_INTERMEDIATE_CAS:
        retval = process_option_ca_crl(context, plg_cryptoctx,
                                       req_cryptoctx, idopts,
                                       id_cryptoctx,
                                       value, CATYPE_INTERMEDIATES);
        break;
    case PKINIT_ID_OPT_CRLS:
        retval = process_option_ca_crl(context, plg_cryptoctx,
                                       req_cryptoctx, idopts,
                                       id_cryptoctx,
                                       value, CATYPE_CRLS);
        break;
    case PKINIT_ID_OPT_OCSP:
        retval = ENOTSUP;
        break;
    default:
        retval = EINVAL;
        break;
    }
    return retval;
}
static krb5_error_code
process_option_identity(krb5_context context,
                        pkinit_plg_crypto_context plg_cryptoctx,
                        pkinit_req_crypto_context req_cryptoctx,
                        pkinit_identity_opts *idopts,
                        pkinit_identity_crypto_context id_cryptoctx,
                        const char *value)
{
    const char *residual;
    int idtype;
    krb5_error_code retval = 0;

    pkiDebug("%s: processing value '%s'\n",
             __FUNCTION__, value ? value : "NULL");
    if (value == NULL)
        return EINVAL;

    residual = strchr(value, ':');
    if (residual != NULL) {
        unsigned int typelen;
        residual++; /* skip past colon */
        typelen = residual - value;
        if (strncmp(value, "FILE:", typelen) == 0) {
            idtype = IDTYPE_FILE;
#ifndef WITHOUT_PKCS11
        } else if (strncmp(value, "PKCS11:", typelen) == 0) {
            idtype = IDTYPE_PKCS11;
#endif
        } else if (strncmp(value, "PKCS12:", typelen) == 0) {
            idtype = IDTYPE_PKCS12;
        } else if (strncmp(value, "DIR:", typelen) == 0) {
            idtype = IDTYPE_DIR;
        } else if (strncmp(value, "ENV:", typelen) == 0) {
            idtype = IDTYPE_ENVVAR;
        } else {
            pkiDebug("%s: Unsupported type while processing '%s'\n",
                     __FUNCTION__, value);
            krb5_set_error_message(context, KRB5_PREAUTH_FAILED,
                                   "Unsupported type while processing '%s'\n",
                                   value);
            return KRB5_PREAUTH_FAILED;
        }
    } else {
        idtype = IDTYPE_FILE;
        residual = value;
    }

    idopts->idtype = idtype;
    pkiDebug("%s: idtype is %s\n", __FUNCTION__, idtype2string(idopts->idtype));
    switch (idtype) {
    case IDTYPE_ENVVAR:
        return process_option_identity(context, plg_cryptoctx, req_cryptoctx,
                                       idopts, id_cryptoctx, getenv(residual));
        break;
    case IDTYPE_FILE:
        retval = parse_fs_options(context, idopts, residual);
        break;
    case IDTYPE_PKCS12:
        retval = parse_pkcs12_options(context, idopts, residual);
        break;
#ifndef WITHOUT_PKCS11
    case IDTYPE_PKCS11:
        retval = parse_pkcs11_options(context, idopts, residual);
        break;
#endif
    case IDTYPE_DIR:
        idopts->cert_filename = strdup(residual);
        if (idopts->cert_filename == NULL)
            retval = ENOMEM;
        break;
    default:
        krb5_set_error_message(context, KRB5_PREAUTH_FAILED,
                               "Internal error parsing X509_user_identity\n");
        retval = EINVAL;
        break;
    }
    return retval;
}
Exemple #3
0
krb5_error_code
pkinit_identity_initialize(krb5_context context,
                           pkinit_plg_crypto_context plg_cryptoctx,
                           pkinit_req_crypto_context req_cryptoctx,
                           pkinit_identity_opts *idopts,
                           pkinit_identity_crypto_context id_cryptoctx,
                           int do_matching,
                           krb5_principal princ)
{
    krb5_error_code retval = EINVAL;
    int i;

    pkiDebug("%s: %p %p %p\n", __FUNCTION__, context, idopts, id_cryptoctx);
    if (!(princ && krb5_principal_compare_any_realm (context, princ, krb5_anonymous_principal()))) {
        if (idopts == NULL || id_cryptoctx == NULL)
            goto errout;

        /*
         * If identity was specified, use that.  (For the kdc, this
         * is specified as pkinit_identity in the kdc.conf.  For users,
         * this is specified on the command line via X509_user_identity.)
         * If a user did not specify identity on the command line,
         * then we will try alternatives which may have been specified
         * in the config file.
         */
        if (idopts->identity != NULL) {
            retval = process_option_identity(context, plg_cryptoctx,
                                             req_cryptoctx, idopts,
                                             id_cryptoctx, idopts->identity);
        } else if (idopts->identity_alt != NULL) {
            for (i = 0; retval != 0 && idopts->identity_alt[i] != NULL; i++) {
                retval = process_option_identity(context, plg_cryptoctx,
                                                 req_cryptoctx, idopts,
                                                 id_cryptoctx,
                                                 idopts->identity_alt[i]);
            }
        } else {
            pkiDebug("%s: no user identity options specified\n", __FUNCTION__);
            goto errout;
        }
        if (retval)
            goto errout;

        retval = crypto_load_certs(context, plg_cryptoctx, req_cryptoctx,
                                   idopts, id_cryptoctx, princ);
        if (retval)
            goto errout;

        if (do_matching) {
            retval = pkinit_cert_matching(context, plg_cryptoctx,
                                          req_cryptoctx, id_cryptoctx, princ);
            if (retval) {
                pkiDebug("%s: No matching certificate found\n", __FUNCTION__);
                crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx,
                                      id_cryptoctx);
                goto errout;
            }
        } else {
            /* Tell crypto code to use the "default" */
            retval = crypto_cert_select_default(context, plg_cryptoctx,
                                                req_cryptoctx, id_cryptoctx);
            if (retval) {
                pkiDebug("%s: Failed while selecting default certificate\n",
                         __FUNCTION__);
                crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx,
                                      id_cryptoctx);
                goto errout;
            }
        }

        retval = crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx,
                                       id_cryptoctx);
        if (retval)
            goto errout;
    } /* Not anonymous principal */

    for (i = 0; idopts->anchors != NULL && idopts->anchors[i] != NULL; i++) {
        retval = process_option_ca_crl(context, plg_cryptoctx, req_cryptoctx,
                                       idopts, id_cryptoctx,
                                       idopts->anchors[i], CATYPE_ANCHORS);
        if (retval)
            goto errout;
    }
    for (i = 0; idopts->intermediates != NULL
             && idopts->intermediates[i] != NULL; i++) {
        retval = process_option_ca_crl(context, plg_cryptoctx, req_cryptoctx,
                                       idopts, id_cryptoctx,
                                       idopts->intermediates[i],
                                       CATYPE_INTERMEDIATES);
        if (retval)
            goto errout;
    }
    for (i = 0; idopts->crls != NULL && idopts->crls[i] != NULL; i++) {
        retval = process_option_ca_crl(context, plg_cryptoctx, req_cryptoctx,
                                       idopts, id_cryptoctx, idopts->crls[i],
                                       CATYPE_CRLS);
        if (retval)
            goto errout;
    }
    if (idopts->ocsp != NULL) {
        retval = ENOTSUP;
        goto errout;
    }

errout:
    return retval;
}