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 ec_flags(krb5_context context, krb5_preauthtype pa_type)
42 static krb5_error_code
43 ec_process(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_pa_data ***out_padata)
52 krb5_error_code retval = 0;
53 krb5_keyblock *challenge_key = NULL, *armor_key, *as_key;
55 armor_key = cb->fast_armor(context, rock);
56 retval = cb->get_as_key(context, rock, &as_key);
57 if (retval == 0 && padata->length) {
58 krb5_enc_data *enc = NULL;
60 scratch.length = padata->length;
61 scratch.data = (char *) padata->contents;
62 retval = krb5_c_fx_cf2_simple(context,armor_key, "kdcchallengearmor",
63 as_key, "challengelongterm",
66 retval = decode_krb5_enc_data(&scratch, &enc);
69 scratch.data = malloc(enc->ciphertext.length);
70 scratch.length = enc->ciphertext.length;
71 if (scratch.data == NULL)
75 retval = krb5_c_decrypt(context, challenge_key,
76 KRB5_KEYUSAGE_ENC_CHALLENGE_KDC, NULL,
79 * Per draft 11 of the preauth framework, the client MAY but is not
80 * required to actually check the timestamp from the KDC other than to
81 * confirm it decrypts. This code does not perform that check.
84 krb5_free_data_contents(context, &scratch);
85 /* If we had a callback to assert that the KDC is verified, we would
88 krb5_free_enc_data(context, enc);
89 } else if (retval == 0) { /*No padata; we send*/
91 krb5_pa_data **pa = NULL;
92 krb5_data *encoded_ts = NULL;
94 enc.ciphertext.data = NULL;
95 retval = krb5_us_timeofday(context, &ts.patimestamp, &ts.pausec);
97 retval = encode_krb5_pa_enc_ts(&ts, &encoded_ts);
99 retval = krb5_c_fx_cf2_simple(context,
100 armor_key, "clientchallengearmor",
101 as_key, "challengelongterm",
104 retval = krb5_encrypt_helper(context, challenge_key,
105 KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT,
108 krb5_free_data(context, encoded_ts);
111 retval = encode_krb5_enc_data(&enc, &encoded_ts);
112 krb5_free_data_contents(context, &enc.ciphertext);
115 pa = calloc(2, sizeof(krb5_pa_data *));
120 pa[0] = calloc(1, sizeof(krb5_pa_data));
125 pa[0]->length = encoded_ts->length;
126 pa[0]->contents = (unsigned char *) encoded_ts->data;
127 pa[0]->pa_type = KRB5_PADATA_ENCRYPTED_CHALLENGE;
128 encoded_ts->data = NULL;
133 krb5_free_data(context, encoded_ts);
136 krb5_free_keyblock(context, challenge_key);
141 static krb5_preauthtype ec_types[] = {
142 KRB5_PADATA_ENCRYPTED_CHALLENGE, 0};
145 clpreauth_encrypted_challenge_initvt(krb5_context context, int maj_ver,
146 int min_ver, krb5_plugin_vtable vtable)
148 krb5_clpreauth_vtable vt;
151 return KRB5_PLUGIN_VER_NOTSUPP;
152 vt = (krb5_clpreauth_vtable)vtable;
153 vt->name = "encrypted_challenge";
154 vt->pa_type_list = ec_types;
155 vt->flags = ec_flags;
156 vt->process = ec_process;