1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/krb/preauth_ec.c - Encrypted Challenge clpreauth module */
4 * Copyright (C) 2009, 2011 by the Massachusetts Institute of Technology.
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
28 * Implement Encrypted Challenge fast factor from
29 * draft-ietf-krb-wg-preauth-framework
33 #include <krb5/preauth_plugin.h>
34 #include "int-proto.h"
37 preauth_flags(krb5_context context, krb5_preauthtype pa_type)
42 static krb5_error_code
43 process_preauth(krb5_context context, krb5_clpreauth_moddata moddata,
44 krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt,
45 krb5_clpreauth_callbacks cb,
46 krb5_clpreauth_rock rock, krb5_kdc_req *request,
47 krb5_data *encoded_request_body,
48 krb5_data *encoded_previous_request, krb5_pa_data *padata,
49 krb5_prompter_fct prompter, void *prompter_data,
50 krb5_clpreauth_get_as_key_fn gak_fct, void *gak_data,
51 krb5_data *salt, krb5_data *s2kparams, krb5_keyblock *as_key,
52 krb5_pa_data ***out_padata)
54 krb5_error_code retval = 0;
56 krb5_keyblock *challenge_key = NULL, *armor_key;
58 armor_key = cb->fast_armor(context, rock);
59 enctype = cb->get_etype(context, rock);
60 if (as_key->length == 0 ||as_key->enctype != enctype) {
61 retval = gak_fct(context, request->client,
62 enctype, prompter, prompter_data,
66 if (retval == 0 && padata->length) {
67 krb5_enc_data *enc = NULL;
69 scratch.length = padata->length;
70 scratch.data = (char *) padata->contents;
71 retval = krb5_c_fx_cf2_simple(context,armor_key, "kdcchallengearmor",
72 as_key, "challengelongterm",
75 retval = decode_krb5_enc_data(&scratch, &enc);
78 scratch.data = malloc(enc->ciphertext.length);
79 scratch.length = enc->ciphertext.length;
80 if (scratch.data == NULL)
84 retval = krb5_c_decrypt(context, challenge_key,
85 KRB5_KEYUSAGE_ENC_CHALLENGE_KDC, NULL,
88 * Per draft 11 of the preauth framework, the client MAY but is not
89 * required to actually check the timestamp from the KDC other than to
90 * confirm it decrypts. This code does not perform that check.
93 krb5_free_data_contents(context, &scratch);
94 /* If we had a callback to assert that the KDC is verified, we would
97 krb5_free_enc_data(context, enc);
98 } else if (retval == 0) { /*No padata; we send*/
100 krb5_pa_data *pa = NULL;
101 krb5_pa_data **pa_array = NULL;
102 krb5_data *encoded_ts = NULL;
104 enc.ciphertext.data = NULL;
105 retval = krb5_us_timeofday(context, &ts.patimestamp, &ts.pausec);
107 retval = encode_krb5_pa_enc_ts(&ts, &encoded_ts);
109 retval = krb5_c_fx_cf2_simple(context,
110 armor_key, "clientchallengearmor",
111 as_key, "challengelongterm",
114 retval = krb5_encrypt_helper(context, challenge_key,
115 KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT,
118 krb5_free_data(context, encoded_ts);
121 retval = encode_krb5_enc_data(&enc, &encoded_ts);
122 krb5_free_data_contents(context, &enc.ciphertext);
125 pa = calloc(1, sizeof(krb5_pa_data));
130 pa_array = calloc(2, sizeof(krb5_pa_data *));
131 if (pa_array == NULL)
135 pa->length = encoded_ts->length;
136 pa->contents = (unsigned char *) encoded_ts->data;
137 pa->pa_type = KRB5_PADATA_ENCRYPTED_CHALLENGE;
142 *out_padata = pa_array;
148 krb5_free_data(context, encoded_ts);
153 krb5_free_keyblock(context, challenge_key);
158 krb5_preauthtype supported_pa_types[] = {
159 KRB5_PADATA_ENCRYPTED_CHALLENGE, 0};
162 clpreauth_encrypted_challenge_initvt(krb5_context context, int maj_ver,
163 int min_ver, krb5_plugin_vtable vtable)
165 krb5_clpreauth_vtable vt;
168 return KRB5_PLUGIN_VER_NOTSUPP;
169 vt = (krb5_clpreauth_vtable)vtable;
170 vt->name = "encrypted_challenge";
171 vt->pa_type_list = supported_pa_types;
172 vt->flags = preauth_flags;
173 vt->process = process_preauth;