xref: /freebsd/crypto/krb5/src/lib/krb5/krb/preauth_encts.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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