2N/A/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2N/A * Copyright 1995, 2003, 2008 by the Massachusetts Institute of Technology. All 2N/A * Export of this software from the United States of America may 2N/A * require a specific license from the United States Government. 2N/A * It is the responsibility of any person or organization contemplating 2N/A * export to obtain such a license before exporting. 2N/A * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 2N/A * distribute this software and its documentation for any purpose and 2N/A * without fee is hereby granted, provided that the above copyright 2N/A * notice appear in all copies and that both that copyright notice and 2N/A * this permission notice appear in supporting documentation, and that 2N/A * the name of M.I.T. not be used in advertising or publicity pertaining 2N/A * to distribution of the software without specific, written prior 2N/A * permission. Furthermore if you modify this software you must label 2N/A * your software as modified software and not distribute it in such a 2N/A * fashion that it might be confused with the original M.I.T. software. 2N/A * M.I.T. makes no representations about the suitability of 2N/A * this software for any purpose. It is provided "as is" without express 2N/A * or implied warranty. 2N/A * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. 2N/A * This file contains routines for establishing, verifying, and any other 2N/A * necessary functions, for utilizing the pre-authentication field of the 2N/A#
endif /* APPLE_PKINIT */ 2N/A/* Open plugin directories for preauth modules. */ 2N/A/* Create the per-krb5_context context. This means loading the modules 2N/A * if we haven't done that yet (applications which never obtain initial 2N/A * credentials should never hit this routine), breaking up the module's 2N/A * list of support pa_types so that we can iterate over the modules more 2N/A * easily, and copying over the relevant parts of the module's table. */ 2N/A /* Only do this once for each krb5_context */ 2N/A /* load the plugins for the current context */ 2N/A /* pull out the module function tables for all of the modules */ 2N/A "preauthentication_client_1",
2N/A /* count how many modules we ended up loading, and how many preauth 2N/A * types we may claim to support as a result */ 2N/A /* allocate the space we need */ 2N/A /* fill in the structure */ 2N/A /* Only call client_fini once per plugin */ 2N/A * Only call request_init and request_fini once per plugin. 2N/A * Only the first module within each plugin will ever 2N/A * have request_context filled in. Every module within 2N/A * the plugin will have its request_context_pp pointing 2N/A * to that entry's request_context. That way all the 2N/A * modules within the plugin share the same request_context 2N/A /* return the result */ 2N/A/* Zero the use counts for the modules herein. Usually used before we 2N/A * start processing any data from the server, at which point every module 2N/A * will again be able to take a crack at whatever the server sent. */ 2N/A * Give all the preauth plugins a look at the preauth option which 2N/A "krb5_preauth_supply_preauth_data: " 2N/A "Unable to initialize preauth context");
2N/A * Go down the list of preauth modules, and supply them with the 2N/A/* Free the per-krb5_context preauth_context. This means clearing any 2N/A * plugin-specific context which may have been created, and then 2N/A * freeing the context itself. */ 2N/A/* Initialize the per-AS-REQ context. This means calling the client_req_init 2N/A * function to give the plugin a chance to allocate a per-request context. */ 2N/A /* Limit this to only one attempt per context? */ 2N/A/* Free the per-AS-REQ context. This means clearing any request-specific 2N/A * context which the plugin may have created. */ 2N/A/* Add the named encryption type to the existing list of ktypes. */ 2N/A * Add the given list of pa_data items to the existing list of items. 2N/A * Factored out here to make reading the do_preauth logic easier to read. 2N/A /* Allocate room for the new additions and a NULL terminator. */ 2N/A * Allocate room for the existing entries plus 2N/A * the new additions and a NULL terminator. 2N/A * Retrieve a specific piece of information required by the plugin and 2N/A * return it in a new krb5_data item. There are separate request_types 2N/A * to obtain the data and free it. 2N/A * This may require massaging data into a contrived format, but it will 2N/A * hopefully keep us from having to reveal library-internal functions 2N/A * or data to the plugin modules. 2N/A/* Tweak the request body, for now adding any enctypes which the module claims 2N/A * to add support for to the list, but in the future perhaps doing more 2N/A * involved things. */ 2N/A /* Add the module-specific enctype list to the request, but only if 2N/A * it's something we can safely modify. */ 2N/A/* Find the first module which provides for the named preauth type which also 2N/A * hasn't had a chance to run yet (INFO modules don't count, because as a rule 2N/A * they don't generate preauth data), and run it. */ 2N/A /* iterate over all loaded modules */ 2N/A /* skip over those which don't match the preauth type */ 2N/A /* skip over those which don't match the flags (INFO vs REAL, mainly) */ 2N/A /* if it's a REAL module, try to call it only once per library call */ 2N/A /* run the module's callback function */ 2N/A /* Make note of the module's flags and status. */ 2N/A /* Save the new preauth data item. */ 2N/A /* Solaris Kerberos */ 2N/A /* now get the time of day, and encrypt it accordingly */ 2N/A label =
"Challenge for Enigma Logic mechanism";
2N/A label =
"Challenge for Digital Pathways mechanism";
2N/A label =
"Challenge for Activcard mechanism";
2N/A label =
"Challenge for Security Dynamics mechanism";
2N/A label =
"Challenge for Security Dynamics mechanism";
2N/A label =
"Challenge from authentication server";
2N/A/* this macro expands to the int,ptr necessary for "%.*s" in an sprintf */ 2N/A/* XXX Danger! This code is not in sync with the kerberos-password-02 2N/A draft. This draft cannot be implemented as written. This code is 2N/A compatible with earlier versions of mit krb5 and cygnus kerbnet. */ 2N/A /* these two get encrypted and stuffed in to sam_response */ 2N/A /* Solaris Kerberos */ 2N/A /* If we need the password from the user (USE_SAD_AS_KEY not set), */ 2N/A /* then get it here. Exception for "old" KDCs with CryptoCard */ 2N/A /* support which uses the USE_SAD_AS_KEY flag, but still needs pwd */ 2N/A /* etype has either been set by caller or by KRB5_PADATA_ETYPE_INFO */ 2N/A /* message from the KDC. If it is not set, pick an enctype that we */ 2N/A /* think the KDC will have for us. */ 2N/A /* sprintf(prompt, "Challenge is [%s], %s: ", challenge, prompt); */ 2N/A /* PROMPTER_INVOCATION */ 2N/A /* XXX What if more than one flag is set? */ 2N/A /* Most of this should be taken care of before we get here. We */ 2N/A /* will need the user's password and as_key to encrypt the SAD */ 2N/A /* and we want to preserve ordering of user prompts (first */ 2N/A /* password, then SAM data) so that user's won't be confused. */ 2N/A /* generate a salt using the requested principal */ 2N/A /* generate a key using the supplied password */ 2N/A /* encrypt the passcode with the key from above */ 2N/A /* process the key as password */ 2N/A /* XXX As of the passwords-04 draft, no enctype is specified, 2N/A the server uses ENCTYPE_DES_CBC_MD5. In the future the 2N/A server should send a PA-SAM-ETYPE-INFO containing the enctype. */ 2N/A /* Eventually, combine SAD with long-term key to get 2N/A /* copy things from the challenge */ 2N/A /* encode the encoded part of the response */ 2N/A /* sam_enc_key is reserved for future use */ 2N/A * PKINIT. One function to generate AS-REQ, one to parse AS-REP 2N/A * Trusted CA list and specific KC cert optionally obtained via 2N/A * krb5_pkinit_get_server_certs(). All are DER-encoded certs. 2N/A /* If we don't have a client cert, we're done */ 2N/A /* optional platform-dependent CA list and KDC cert */ 2N/A /* checksum of the encoded KDC-REQ-BODY */ 2N/A /* cook up a random 4-byte nonce */ 2N/A /* free data mallocd by krb5_pkinit_get_server_certs() */ 2N/A/* If and only if the realm is that of a Local KDC, accept 2N/A * the KDC certificate as valid if its hash matches the 2N/A /* If we don't have a client cert, we're done */ 2N/A /* calculate checksum of incoming AS-REQ using the decryption key 2N/A * we just got from the ReplyKeyPack */ 2N/A /* We have the key; transfer to caller */ 2N/A#
endif /* APPLE_PKINIT */ 2N/A /* All of the above error checks are KDC-specific, that is, they */ 2N/A /* assume a failure in the KDC reply. By returning anything other */ 2N/A /* than KRB5_KDC_UNREACH, KRB5_PREAUTH_FAILED, */ 2N/A /* KRB5_LIBOS_PWDINTR, or KRB5_REALM_CANT_RESOLVE, the client will */ 2N/A /* most likely go on to try the AS_REQ against master KDC */ 2N/A /* We will need the password to obtain the key used for */ 2N/A /* the checksum, and encryption of the sam_response. */ 2N/A /* Go ahead and get it now, preserving the ordering of */ 2N/A /* prompts for the user. */ 2N/A /* Generate salt used by string_to_key() */ 2N/A /* Get encryption key to be used for checksum and sam_response */ 2N/A /* as_key = string_to_key(password) */ 2N/A /* generate a key using the supplied password */ 2N/A /* as_key = combine_key (as_key, string_to_key(SAD)) */ 2N/A /* This should be a call to the crypto library some day */ 2N/A /* key types should already match the sam_etype */ 2N/A /* as_key = string_to_key(SAD) */ 2N/A /* generate a key using the supplied password */ 2N/A /* Now we have a key, verify the checksum on the sam_challenge */ 2N/A * If we do not have a keyed checksum, no need to verify 2N/A /* Check this cksum */ 2N/A * Note: We return AP_ERR_BAD_INTEGRITY so upper-level applications 2N/A * can interpret that as "password incorrect", which is probably 2N/A * the best error we can return in this situation. 2N/A /* fill in enc_sam_response_enc_2 */ 2N/A /* encode and encrypt enc_sam_response_enc_2 with as_key */ 2N/A /* Fill in sam_response_2 */ 2N/A /* Now take care of sr2.sam_enc_nonce_or_sad by encrypting encoded */ 2N/A /* enc_sam_response_enc_2 from above */ 2N/A /* Encode the sam_response_2 */ 2N/A /* Almost there, just need to make padata ! */ 2N/A/* FIXME - order significant? */ 2N/A#
endif /* APPLE_PKINIT */ 2N/A * If one of the modules can adjust its AS_REQ data using the contents of the 2N/A * err_reply, return 0. If it's the sort of correction which requires that we 2N/A * ask the user another question, we let the calling application deal with it. 2N/A /* first do all the informational preauths, then the first real one */ 2N/A * This is really gross, but is necessary to prevent 2N/A * lossage when talking to a 1.0.x KDC, which returns an 2N/A * erroneous PA-PW-SALT when it returns a KRB-ERROR 2N/A * requiring additional preauth. 2N/A ret = 0;
/*Ignore error and etype_info element*/ 2N/A * Select first etype in our request which is also in 2N/A * etype-info (preferring client request ktype order). 2N/A /* check if program has support for this etype for more 2N/A * precise error reporting. 2N/A /* supported enctype but not requested */ 2N/A /* unsupported enctype */ 2N/A /* Try the internally-provided preauth type list. */ 2N/A "internal function for type %d, flag %d " 2N/A "failed with err %d\n",
2N/A continue;
/* PA_INFO type failed, ignore */ 2N/A /* Try to use plugins now. */