1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/krb/preauth_encts.c - Encrypted timestamp clpreauth module */
3 /*
4 * Copyright 1995, 2003, 2008, 2011 by the Massachusetts Institute of Technology. All
5 * Rights Reserved.
6 *
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.
11 *
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.
25 *
26 */
27
28 #include <k5-int.h>
29 #include <krb5/clpreauth_plugin.h>
30 #include "int-proto.h"
31 #include "init_creds_ctx.h"
32
33 static krb5_error_code
encts_prep_questions(krb5_context context,krb5_clpreauth_moddata moddata,krb5_clpreauth_modreq modreq,krb5_get_init_creds_opt * opt,krb5_clpreauth_callbacks cb,krb5_clpreauth_rock rock,krb5_kdc_req * request,krb5_data * encoded_request_body,krb5_data * encoded_previous_request,krb5_pa_data * pa_data)34 encts_prep_questions(krb5_context context, krb5_clpreauth_moddata moddata,
35 krb5_clpreauth_modreq modreq,
36 krb5_get_init_creds_opt *opt, krb5_clpreauth_callbacks cb,
37 krb5_clpreauth_rock rock, krb5_kdc_req *request,
38 krb5_data *encoded_request_body,
39 krb5_data *encoded_previous_request,
40 krb5_pa_data *pa_data)
41 {
42 krb5_init_creds_context ctx = (krb5_init_creds_context)rock;
43
44 if (!ctx->encts_disabled)
45 cb->need_as_key(context, rock);
46 return 0;
47 }
48
49 static krb5_error_code
encts_process(krb5_context context,krb5_clpreauth_moddata moddata,krb5_clpreauth_modreq modreq,krb5_get_init_creds_opt * opt,krb5_clpreauth_callbacks cb,krb5_clpreauth_rock rock,krb5_kdc_req * request,krb5_data * encoded_request_body,krb5_data * encoded_previous_request,krb5_pa_data * padata,krb5_prompter_fct prompter,void * prompter_data,krb5_pa_data *** out_padata)50 encts_process(krb5_context context, krb5_clpreauth_moddata moddata,
51 krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt,
52 krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock,
53 krb5_kdc_req *request, krb5_data *encoded_request_body,
54 krb5_data *encoded_previous_request, krb5_pa_data *padata,
55 krb5_prompter_fct prompter, void *prompter_data,
56 krb5_pa_data ***out_padata)
57 {
58 krb5_init_creds_context ctx = (krb5_init_creds_context)rock;
59 krb5_error_code ret;
60 krb5_pa_enc_ts pa_enc;
61 krb5_data *ts = NULL, *enc_ts = NULL;
62 krb5_enc_data enc_data;
63 krb5_pa_data **pa = NULL;
64 krb5_keyblock *as_key;
65
66 enc_data.ciphertext = empty_data();
67
68 if (ctx->encts_disabled) {
69 TRACE_PREAUTH_ENC_TS_DISABLED(context);
70 k5_setmsg(context, KRB5_PREAUTH_FAILED,
71 _("Encrypted timestamp is disabled"));
72 return KRB5_PREAUTH_FAILED;
73 }
74
75 ret = cb->get_as_key(context, rock, &as_key);
76 if (ret)
77 goto cleanup;
78 TRACE_PREAUTH_ENC_TS_KEY_GAK(context, as_key);
79
80 /*
81 * Try and use the timestamp of the preauth request, even if it's
82 * unauthenticated. We could be fooled into making a preauth response for
83 * a future time, but that has no security consequences other than the
84 * KDC's audit logs. If kdc_timesync is not configured, then this will
85 * just use local time.
86 */
87 ret = cb->get_preauth_time(context, rock, TRUE, &pa_enc.patimestamp,
88 &pa_enc.pausec);
89 if (ret)
90 goto cleanup;
91
92 ret = encode_krb5_pa_enc_ts(&pa_enc, &ts);
93 if (ret)
94 goto cleanup;
95
96 ret = krb5_encrypt_helper(context, as_key, KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS,
97 ts, &enc_data);
98 if (ret)
99 goto cleanup;
100 TRACE_PREAUTH_ENC_TS(context, pa_enc.patimestamp, pa_enc.pausec,
101 ts, &enc_data.ciphertext);
102
103 ret = encode_krb5_enc_data(&enc_data, &enc_ts);
104 if (ret)
105 goto cleanup;
106
107 pa = k5calloc(2, sizeof(krb5_pa_data *), &ret);
108 if (pa == NULL)
109 goto cleanup;
110
111 pa[0] = k5alloc(sizeof(krb5_pa_data), &ret);
112 if (pa[0] == NULL)
113 goto cleanup;
114
115 pa[0]->magic = KV5M_PA_DATA;
116 pa[0]->pa_type = KRB5_PADATA_ENC_TIMESTAMP;
117 pa[0]->length = enc_ts->length;
118 pa[0]->contents = (krb5_octet *) enc_ts->data;
119 enc_ts->data = NULL;
120 pa[1] = NULL;
121 *out_padata = pa;
122 pa = NULL;
123
124 cb->disable_fallback(context, rock);
125
126 cleanup:
127 krb5_free_data(context, ts);
128 krb5_free_data(context, enc_ts);
129 free(enc_data.ciphertext.data);
130 free(pa);
131 return ret;
132 }
133
134 static krb5_preauthtype encts_pa_types[] = {
135 KRB5_PADATA_ENC_TIMESTAMP, 0};
136
137 krb5_error_code
clpreauth_encrypted_timestamp_initvt(krb5_context context,int maj_ver,int min_ver,krb5_plugin_vtable vtable)138 clpreauth_encrypted_timestamp_initvt(krb5_context context, int maj_ver,
139 int min_ver, krb5_plugin_vtable vtable)
140 {
141 krb5_clpreauth_vtable vt;
142
143 if (maj_ver != 1)
144 return KRB5_PLUGIN_VER_NOTSUPP;
145 vt = (krb5_clpreauth_vtable)vtable;
146 vt->name = "encrypted_timestamp";
147 vt->pa_type_list = encts_pa_types;
148 vt->prep_questions = encts_prep_questions;
149 vt->process = encts_process;
150 return 0;
151 }
152